Key-Chord Mode for GNU Emacs

Today I want to introduce you to a useful package for Emacs: Key-Chord Mode by David Andersson. It allows you to define and use key-chords in a manner similar to Vim. Long-time Emacs users may consider it heresy to use anything remotely close to Vim. But perhaps I can convince you to try Key-Chord Mode.


Installing Key-Chord Mode is simple. Place the key-chord.el file where Emacs can find it, i.e. in your load path (use C-h v info-path for help). Then add the following to your Emacs configuration file:

(require 'key-chord)
(key-chord-mode 1)

This will enable the mode globally. However, this only makes the mode available. It comes with no pre-defined chords, so let’s look at how we create and use those.

Creating and Using Chords

Key-Chord Mode defines a ‘chord’ as two keys pressed in rapid succession, or the same key quickly pressed twice. When I say ‘quickly’ I mean less than half a second. You can configure that delay, but personally I have found the defaults to be comfortable.

Here is an example chord definition which I use:

(key-chord-define-global ",," 'fill-paragraph)

The first argument is the two characters representing the chord. The second is the command to execute. So when I quickly press the comma key twice Emacs runs the fill-paragraph command to indent and wrap the text of the current paragraph I’m writing. Here is another example, a chord which I used when typing the fill-paragraph command each time in this paragraph:

(key-chord-define-global "jj" 'dabbrev-expand)

The command dabbrev-expand is one of Emacs’ built-in systems of auto-completion. So if I type dab and then hit the j key twice Emacs will expand that into dabbrev-expand. I find this useful not only when writing documents like this, but also when I am programming. Pressing one key twice is a simple and efficient way to auto-complete function names, or variable names, and so forth.

Pay careful attention to the chord characters I use.

The two chords I’ve shown thus far are ,, and jj. These are not entirely arbitrary choices. I decided on those specific characters because I never type them under normal circumstances. When you define chords you must consider how likely it is that you will type the chord characters by accident. Here is a list of some chords that would be poor choices for English speakers and writers:

  • .. Typing ellipses would require a pause between each period.

  • ed This is a common verb ending and appears frequently in English.

  • ou This is another combination found in many English words.

  • << Some programming languages use these characters as an operator, e.g. C++.

  • -- Likewise for this chord, e.g. $foo--;.

This should demonstrate the problems you can run into if you do not carefully consider the chords you define. Do not make chords out of any two-character sequence that you type on an even semi-frequently basis, let alone anything you type commonly. One way I avoid this is by using capital letters. For example:

(key-chord-define-global "JJ" 'find-tag)
(key-chord-define-global "BB" 'ido-switch-buffer)
(key-chord-define-global "FF" 'ido-find-file)
(key-chord-define-global "##" 'server-edit)
(key-chord-define-global "VV" 'other-window)

I have to hold down the Shift key to use any of these chords, but they are still comfortable to type in my opinion. And notice that I use both jj and JJ as chords. Key-Chord Mode allows you to make distinctions like this based on the case of the characters.

By now you have surely noticed that I prefer to repeat a single character for most chords. That is only my preference, not a requirement of the mode. Here are some examples from the source code demonstrating a variety of chords:

(key-chord-define-global ",."     "<>\C-b")
(key-chord-define-global "hj"     'undo)
(key-chord-define-global [?h ?j]  'undo)  ; the same
(key-chord-define-global "jk"     'dabbrev-expand)
(key-chord-define-global "cv"     'reindent-then-newline-and-indent)
(key-chord-define-global "4r"     "$")
(key-chord-define-global "''"     "`'\C-b")
(key-chord-define-global ",,"     'indent-for-comment)
(key-chord-define-global "qq"     "the ")
(key-chord-define-global "QQ"     "The ")
(key-chord-define c++-mode-map ";;"  "\C-e;")
(key-chord-define c++-mode-map "{}"  "{\n\n}\C-p\t")

Note well that…

  1. You can define chords using a vector of characters instead of a string.

  2. The result of a chord can be a string of characters to insert into the buffer.

  3. Such a string can also contain other key-sequences. So the first example in the list above enters the characters <> and then places the cursor between them by moving back one, simulating the use of C-b.

  4. You can restrict chords to specific modes, as in the last two examples.


I hope this provides you with a decent overview of what Key-Chord Mode offers. It does not allow you to create chords longer than two characters (not counting modifiers like Shift). However, I have not found that limitation to be a problem.

Personally I believe using Key-Chord Mode has improved the speed at which I accomplish certain tasks in Emacs. Granted, I am talking about tiny gains. But they add up since I use chords for commands that I invoke multiple times on a daily basis. And it helps relieve problems with ‘Emacs Pinky’, although a good keyboard and remapping of the Control key helps tremendously in that regard.

Give Key-Chord Mode a try. Create some chords for commands you frequently use and see how it feels. I would never claim that it is for everyone, but the quality of the package deserves a little bit of your time for a test run.


5 thoughts on “Key-Chord Mode for GNU Emacs

    1. Good point. I can see how it would cause delays, but in my experience I rarely get lag. So I forgot to mention that possibility in the article.

    1. I don’t think abbrev-mode is inherently better, and certainly not faster to use than dabbrev-expand since ninety-nine percent of the time I am expanding some variable or function name that already exists in an open buffer.

Add Your Thoughts

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s