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.
Installation
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…
-
You can define chords using a vector of characters instead of a string.
-
The result of a chord can be a string of characters to insert into the buffer.
-
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 ofC-b
. -
You can restrict chords to specific modes, as in the last two examples.
Conclusion
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.
Beware that using key-chord may cause Emacs to be laggy when you type.
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.
[…] it, and have been using it ever since. I’m mentioning it again because Eric Ritz recently posted about […]
A better way to expand common words is to use abbrev-mode.
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.