On Defining Keys In Emacs
1 Overview
Emacs is extremely flexible with respect to letting you bind keys to commands. Interestingly, and perhaps because of its history tracing back to keyboard macros, naming the key you wish to bind is not so straight-forward as it appears on the surface. Here are things I've used and learnt over the last 30 years of Emacs hackery:
- The most basic way of naming a key is via a string of the form \C-a or \M-\C-a where \C denotes the Control Modifier.
- This notation gets unwieldy fast when using multiple modifiers as in the \M-\C-a example.
- It gets worse, under X, you can bind \C- / for /Control Space — notice that the space character here which is easy to miss as white-space is significant.
- The \<modifier>-char notation mostly appears to date back to the age of the terminal emulator (tty), so for example, it cannot denote Control+Right for example.
- The Emacs and Elisp info manuals recommend using function kbd for this reason, this function on the surface provides a unified interface for naming keys.
If you look no further, you remain happy, but …
2 Function kbd
But if you do peel the onion, here is what you find:
- Function
kbd
does nothing more than calling functionread-kbd-macro
. - Function
read-kbd-macro
documents itself as reading the region as a keyboard macro. - The above overloading is achieved by the call to function
edmacro-parse-keys
. - And finally we reach the scary core of the onion that is sufficient to make your eyes water!
- Function
edmacro-parse-keys
is an inscrutable piece of code that both looks extremely clever and magical and like all clever code, feels fragile.
3 Understanding And (Hopefully) Simplifying Function kbd
A simplified ems-kbd
function that is free from the complexity
resulting from reading in a saved keyboard macro feels like a
worthwhile goal.
I started down this road both to understand function
edmacro-parse-keys
— sadly, I haven't yet found a specification
for naming all available keys outside of the implementation of that
function.
So I started ems-kbd.el
along with a simple test-suite to see how far I could get toward the
goal of creating an equivalent kbd
function.
3.1 Steps So Far
- Documented the implementation.
- Added a simple set of tests in the file.
- Changed if to cond or when as appropriate.
- Eliminated the logic that handled the keyboard macro serialization for repeated keys.
- Removed the logic for handling invocations of
execute-extended-command
— otherwise known as M-x. - A lot more remains, e.g.,
- simplifying how modifier bits are handled,
- Simplifying how special patterns like SPC or TAB are handled.
- And likely a lot more.
An alternative approach might be to rewrite it from scratch, but that feels intractable unless I can track down a specification for naming keys that is exhaustive with respect to the various conventions that have been used over the years.