Xah Lee, 2007-07
Emacs's default keybindings are very ergonomically painful, for several reasons. (For detail, see: Why Emacs's Keyboard Shortcuts Are Painful.) This page shows a redesign of emacs's shortcut set, based on ergonomic principles.
Here's the outline of how this design is arrived.
All the commands that has a default shortcut of M-‹key› and C-‹key› are listed. This command set is then ordered by their frequency of use. Then, commands with higher frequency of use are mapped to the most easy-to-press keys. Specifically: Meta (Alt under the thumb) combination is easier than Control, home keys are easier than non-home keys, and keys pressed by the index and middle fingers are better than keys pressed by the ring finger and little finger. (this design principle is similar to the design principle of Dvorak keyboard layout↗.)
(For a statistics of command frequency, see Emacs Commands Frequency.)
Secondarily, similar commands are placed together. For example, forward-char, backward-char, previous-line, next-line (these are the arrow key commands) are all mapped to the right hand's home position in a inverted T layout. Copy/cut/paste are in a row and adjacent to each other. By placing similar commands together, the keyboard shortcuts are made easier to remember. If we strictly go by command frequency with ease-of-key-press, then similar commands will be scattered all over. By placing similar commands together, the logical positioning makes it more coherent and easier to use, with no decrease in speed of execution. (because keyboard shortcuts are not executed continuously like typing.)
Of Emacs's shortcut set, the most frequently used commands can be grouped into 3 categories: (1) Those move the cursor. (2) those manipulate text. (3) Other. Cursor moving commands include moving the cursor to beginning/ending of char/word/line/sentence/paragraph/screenful/file. Text editing commands includes copy/cut/paste, paste previous (yank-pop), kill-word, backward-kill-word, kill-line, and some text transformations such as fill-paragraph, just-one-space, comment-dwim, etc. Also, commands such as mark-paragraph, are considered in this group. The third group, are commands such as execute-extended-command (M-x), keyboard-quit (C-g), toggle-input-method (C-\), universal-argument (C-u), help system (C-h ‹key›) etc.
In the Dvorak layout design, all vows are placed on the left hand's home row, and the most frequently used consonants are placed on the right hand's home row. The idea is that hands will alternate. We borrow this idea, by placing all cursor movement commands under the right hand, and all text editing commands (such as copy/cut/paste/kill-word/kill-line) under the left hand.
The following shows the layout of this design.
In this design, only the M-‹key› shortcuts are redefined. (and with some Meta-shift definition as well). Shortcuts involving Control key, or any other key sequence, are untouched. This is so to avoid radical change that will require a lot coding efforts on every major and minor mode's keymaps. Emacs's default shortcut does not put much weight on commands using the Meta+‹key› space, and does not use Meta+Shift+letter combinations. By using the single-key shortcut space of M-‹key›, the operation and consistency of emacs's shortcuts are practically unaffected, while the most frequently used commands now have home-row keystrokes with the thumb down.
In this design, the layout is the same on QWERTY and Dvorak keyboard layout, because it is based on finger positions and not on command name's first letters.
This colored commands means holding down the Meta/Alt key. This colored commands means holding down both Meta and Shift. A blank key means it is unaltered from emacs's default command keybinding for that key.
For clarity, some command names are replaced with glyphs. Here's what they mean:
← backward-char → forward-char ↑ previous-line ↓ next-line ←w backward-word →w forward-word ←s backward-sentence →s forward-sentence ↑¶ backward-paragraph ↓¶ forward-paragraph |
|← move-beginning-of-line →| move-end-of-line ▲ scroll-down (page up) ▼ scroll-up (page down) |◀ beginning-of-buffer ▶| end-of-buffer |
⌦ delete-char
⌫ delete-backward-char
⌦w kill-word
⌫w backward-kill-word
⌦l kill-line
⌦s kill-sentence
copy kill-ring-save
✂ kill-region (cut)
paste yank
paste yank-pop
previous
M-x execute-extended-command
|
Here's the emacs lisp file for the above ergonomic keybinding design. ergonomic_keybinding_dvorak.el and ergonomic_keybinding_qwerty.el. Please send your comments or suggestions.
The following table shows commands that are displaced by this rebinding. Those with a asterisk * means they are included in the rebinding elsewhere. Those without a asterisk will no longer have a shortcut. If you need them, you will need to bind them:
| QWERTY | Dvorak |
|---|---|
forward-word * backward-sentence forward-sentence move-to-window-line tab-to-tab-stop kill-word * kill-sentence kill-ring-save * just-one-space indent-new-comment-line downcase-word upcase-word center-line default prefix M-o tmm-menubar |
backward-sentence forward-sentence move-to-window-line kill-word * downcase-word upcase-word capitalize-word transpose-words just-one-space tags-loop-continue find-tag default prefix M-g tmm-menubar |
For historical reasons, emacs do not use any keybindings involving the Shift with a letter. (e.g. there's no “meta shift a”, or “control shift a”) This is so because in early computing environment, such key combination cannot be distinguished, due to a practical combination of ASCII↗, Computer terminal↗, telnet↗.
Today, however, employing the Shift key as part of a shortcut with other modifiers is common and convenient. For example, on Mac OS X, Undo and Redo are Cmd+z and Cmd+Shift+z, Save and Save As are Cmd+s and Cmd+Shift+s. On Mac and Windows, moving to next/previous field/window/application often use the Shift key for reversing direction. In text editing on both Mac and Windows, a modifier and a arrow key will move cursor by word/paragraph, and with Shift down will select them while moving.
Using the Shift key as a reverse operation is very easy to remember, and doesn't take another precious shortcut space.
In this keybinding design, Shift is used in a few places by the same principle. Such shortcut may (or may not) be recognized if you use emacs remotely thru telnet/ssh. However, it should not present any problem since you can fall back to emacs's default keybindings involving the Control, or simply use the physical special keys such as the arrow keys, Backspace, Home/End.
You can unbind the many default shortcuts such as the major cursor movements shortcuts: C-p, C-n, C-f, C-b, C-a, C-e, C-v, M-v, and the major text-changing shortcuts C-w, C-y, C-/, C-k, C-SPC. You can do so like this: “(global-unset-key (kbd "C-n"))”. (See this file for a template xah_emacs_kbd_shortcuts.el)
Note that some mini-buffer or special mode (such as calc, shell-command, isearch-forward), may rebind one of our cursor movement shortcut. (Example: while in the minibuffer invoked by isearch-forward, it redefines M-r. Another example: in calc, it disregard any keybindings made with global-set-key.)
For practical purposes, in these special modes you can fall back to emacs's Control key based shortcuts. However, if you have undefined them (because you want to kick the habit), you can just resort to the physical special keys such as the arrow keys, Backspace, Home/End.
On the subject of keyboarding ergonomics, a user may wonder whether switching from QWERTY to Dvorak provides a better improvement than switching from a lousy to better keyboard shortcut layout. (Assuming that he does only one of the above.)
Of my Emacs Commands Frequency study, 37% of key strokes involves data entry (that is, calling the commands “self-insert-command” and “newline” (pressing return), while the rest 63% are calling all other commands. This seems counter-intuitive, because one might think typing should probably be the bulk of activity and moving cursor and deleting text or other commands are only done few times per minute.
If we consider commands invoked by the Backspace key as data entry, then 40% are data entry, while 60% are editing commands. Still surprising. Going one step further, if we consider the next group of most used commands of moving the cursor by the smallest unit (i.e. previous-line (C-p), next-line (C-n), backward-char (C-b), forward-char (C-f) (also invoked by the physical arrow keys)) as part of data entry, then, 64% are data entry and 36% are other command calls.
This data seems to indicate, that a better shortcut layout is as important as a better key layout, at least for computer programing related activities.
In any case, if you are not using a Dvorak layout already, you probably should consider switching to it.
This section discusses some other common commands that are candidates to be incorporated into the ergonomic layout.
One of the top most used command is isearch-forward and isearch-repeat-forward (both are C-s). Together, they are called 1.14% with respect to all non-data-entry commands calls, in about the same frequency as scroll-up (C-v; PageDown), undo (C-_), delete-char (C-d). In our rebinding, the right hand's pinky on the home row (i.e. “;” on QWERTY and “s” on Dvorak) is still not assigned, and “isearch-forward” probably should go there (and with the Shift down will be isearch-backward). However, to redefine keymaps for isearch-forward involves non-trivial elisp coding by redefining its keymap. This is currently not done.
There are several other commands that are frequently used and could be incorporated into this shortcut design. To be conservative, they are currently left out from this keybinding remap (beacuse the ergonomic set in this document currently is restricted to only remapping common cursor movement and text editing commands). These are listed below.
| Standard name | Emacs command name | Default binding | Proposed binding (on Dvorak) | Proposed binding (on QWERTY) |
|---|---|---|---|---|
| Open | find-file/dired | C-x C-f | M-f | M-y |
| - | find-file-at-point | - | M-S-f | M-S-y |
| Close | kill-this-buffer | - | M-b | M-n |
| - | list-buffers/ibuffer | C-x k | M-S-b | M-S-n |
| Save | save-buffer | C-x C-s | M-m | M-m |
| Save As | write-file | C-x C-w | M-S-m | M-S-m |
| Next Tab | «next-user-buffer» | C-x → | M-→ | M-→ |
| Previous Tab | «previous-user-buffer» | C-x ← | M-← | M-← |
| Select All | mark-whole-buffer | C-x h | - | - |
Note: when the find-file command is given a directory path as argument (as opposed to a file's path), it will invoke the dired mode. So, a single shortcut is sufficient to cover both find-file and dired. (this is logical when we consider find-file as the Open command, showing the file browser when given a dir path.)
| Standard name | Emacs command name | Default binding | Proposed binding (on Dvorak) | Proposed binding (on QWERTY) |
|---|---|---|---|---|
| Cancel | keyboard-quit | C-g | ||
| Find | isearch-forward | C-s | M-s | M-; |
| Find previous | isearch-backward | C-r | M-S-s | M-S-; |
The following are some common emacs commands that do text transformation. They are candidates to be considered to have a shortcut in M-‹key› space. (Note that many of them by default have a M-‹key› binding but may be remapped by this design) The following list is just a sample of candidates. In general, candidates should be related to text editing of a general semantics that is useful in most language modes. (For example, the set of commands that marks word/sexp/paragraph/defun/page/buffer could be candidates) A good way to compile candidates is to poll existing emacs users using a actual command recorder, so that we can obtain a factual report on what are the most frequently used commands.
| Standard name | Emacs command name | Default binding | Proposed binding (on Dvorak) | Proposed binding (on QWERTY) |
|---|---|---|---|---|
| abbrev-prefix-mark | M-' | |||
| dabbrev-expand | M-/ | |||
| hard-wrap | fill-paragraph | M-q | ||
| un-hard-wrap | «remove-hard-wrap-paragraph» | |||
| just-one-space | M-SPC | |||
| delete-blank-lines | C-x C-o | |||
| comment-dwim | M-; | |||
| mark-word | M-@ |
Those in «angle brackets» indicate custom functions common to most modern text editors but does not exist in emacs. Here are some explanation of them:
• next-user-buffer (and previous-user-buffer) switchs to the next buffer among user's files. (i.e. skipping emacs internal buffers or those not having to do with normal files. e.g. *scratch*, *Messages*, *shell*, *Shell Command Output*, *Occur*, *Completions*, *Apropos*, *info*, etc.) This is similar to next tab or next window in modern applications. (There should also be a “next-emacs-buffer” and “previous-emacs-buffer” that switchs to these buffers. The next-user-buffer can be assigned to Ctrl+→, and the next-emacs-buffer could be Ctrl+Shift+→.
• remove-hard-wrap-paragraph does the reverse of fill-paragraph. Namely, remove the line endings of the paragraph the current cursor is on.
For lisp code that does the above 3 functions, see modern_operations.el.
Support documents:
General reference on emacs's keybinding:
The use of Shift key in emacs keybindings:
General info about common shortcuts, modifier keys, Dvorak layout.
Page created: 2007-07. © 2007 by Xah Lee.