Xah Lee, 2007-07, ..., 2009-08-20, 2009-09-06
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 emacs package that makes your emacs use a new shortcut set. This shortcut set is designed based on ergonomic principles, based on emacs command call statistics, similar to how Dvorak layout is designed.
Here's the outline of how this design is arrived.
Statistics of emacs commands are compiled from emacs users, and are listed by frequency of use. The top about 30 ones, are given a keyboard shortcut.
To assign the key position, the following rules are used. The rules are listed roughly in order of priority:
The design is based on finger positions, not on first letter of command names. The shortcut set is the same for QWERTY and Dvorak. The ease of remembering what commands are on what keys are based on grouping and positioning. For example, cursor movings are all right hand, text changing are all left hand, moving or deleting to the left/right have keys that are place left and right together, and similar for up/down (by screen or to beginning/end of file). Undo, Cut, Copy, Paste are the familiar row Z X C V.
In this design, only the Meta+‹key› space is used. Some Meta-shift is used too. Ctrl+‹key› space is not used except 7 standard keybindings (Open, Close, Save, Save As, Print, Select All). The operation and consistency of emacs are not affected.
← backward-char ←w backward-word ←¶ backward-paragraph |← move-beginning-of-line → forward-char →w forward-word →¶ forward-paragraph →| move-end-of-line ↑ previous-line ↓ next-line |
▲ scroll-down (page up) ▼ scroll-up (page down) |◀ beginning-of-buffer ▶| end-of-buffer isearch← isearch-backward isearch→ isearch-forward |
⌦ delete-char ⌦w kill-word ⌦| kill-line ⌫ delete-backward-char ⌫w backward-kill-word |⌫ kill-line-backward copy kill-ring-save ✂ kill-region paste yank paste↑ yank-pop M-x execute-extended-command |
Layout image with Dvorak key labels: ErgoEmacs Keybinding Dvorak, and Colemak key labels: ErgoEmacs Keybinding Colemak.
ergoemac-mode minor mode: ergoemacs-keybindings-5.1.zip. (Released on 2009-09-22, tested in emacs 23.1.x.)
If you are on Windows, you can download the ErgoEmacs emacs distribution for Windows. The ErgoEmacs shortcut set is builtin, with lots other added features.
Older version, emacs 22 and emacs 23:
These older versions are provided for whatever reasons people might want them. You shouldn't use it unless you have good reasons. The older version is based on global keymap, not a minor mode. The newer version is a minor mode.
For convenience, the following standard shortcuts are also made available:
| Standard name | Key press | Emacs command name |
|---|---|---|
| Open New File | Ctrl+n | new-empty-buffer |
| Open | Ctrl+o | find-file |
| Close | Ctrl+w | close-current-buffer |
| Save | Ctrl+s | save-buffer |
| Save As | Ctrl+Shift+s | write-file |
| Ctrl+p | print-buffer | |
| Select All | Ctrl+a | mark-whole-buffer |
| Find | Ctrl+f | search-forward |
The command new-empty-buffer (“Ctrl+n”) lets you open any scratch buffer easily. New buffers are named “untitled”, “untitled<2>”, “untitled<3>”, etc.
The new command close-current-buffer (“Ctrl+w”) will prompt you for save when you close a modified buffer. (tech detail)
The following are some new commands that lets you easily switch windows or buffers.
| Standard name | Key press | Emacs command name |
|---|---|---|
| Next Window | Alt+` | next-frame-command |
| Previous Window | Alt+~ | previous-frame-command |
| Next Tab | Ctrl+PageDn | next-user-buffer |
| Previous Tab | Ctrl+PageUp | previous-user-buffer |
| - | Ctrl+Shift+PageDn | next-emacs-buffer |
| - | Ctrl+Shift+PageUp | previous-emacs-buffer |
The following are new commands that combine the functionality of several similar commands into one. This way, you have one single command with one single shortcut to remember. They do what you want depending on context.
| Name | Shortcut | Description |
|---|---|---|
| shrink-whitespaces | Alt+w | Calls either just-one-space or delete-blank-lines depending on context of neighbor text around cursor. |
| compact-uncompact-block | Alt+q | Calls either fill-paragraph, fill-region, or unfill-paragraph, unfill-region, depending on context. (tech detail) |
| toggle-letter-case | Alt+z | Toggles letter case of current word or region. It combines capitalize-word, downcase-word, upcase-word, capitalize-region, downcase-region, upcase-region. (tech detail) |
The following table are commands that are statistically not often used. They no longer have a keyboard shortcut.
| Emacs Commnands | Qwerty | Dvorak |
|---|---|---|
| Cursor Moving | ||
| backward-sentence (Alt+a) | ✗ | ✗ |
| forward-sentence (Alt+e) | ✗ | ✗ |
| move-to-window-line (Alt+r) | ✗ | ✗ |
| center-line (Alt+s) | ✗ | ✗ |
| Text Changing | ||
| kill-sentence (Alt+k) | ✗ | ✗ |
| zap-to-char (Alt+z) | ✗ | ✗ |
| indent-new-comment-line (Alt+j) | ✗ | ✗ |
| transpose-words (Alt+t) | remain | ✗ |
| Other | ||
| facemenu prefix (Alt+g) | ✗ | ✗ |
| eval-expression (Alt+:) | ✗ | ✗ |
| abbrev-prefix-mark (Alt+-) | remain | ✗ |
| tmm-menubar (Alt+') | ✗ | ✗ |
| find-tag (Alt+.) | remain | ✗ |
| tags-loop-continue (Alt+,) | remain | ✗ |
| tab-to-tab-stop (Alt+i) | ✗ | ✗ |
| dabbrev-expand (Alt+/) | ✗ | remain |
If you use these commands often, you can define shortcuts for them. You can now use the “Ctrl+‹key›” space because there are a lot empty space there now. For how to define your own keybindings, see: How to Define Keyboard Shortcuts in Emacs.
On Microsoft Windows, “Ctrl+Shift” or some other combination may switch your Input Language or Keyboard Layout. You can disable this, or change the shortcut to something else. Go to your Windows Control panel, keyboards, Advanced Key Settings tab, then press the button “Change Key Sequence...”. (This describes Windows Vista. Window XP and Windows 7 should be similar.)
On Mac OS X, “Cmd+h” is Hide and “Cmd+Shift+q” is Log Out. If your Meta is Cmd, then the Mac behavior will not be available because ergoemacs uses these keys. If you wish to have the Mac behavior, put the following in your emacs init file:
(setq mac-pass-command-to-system t)
If you are a long time emacs user, you may find it painful to adopt this setup. This difficulty is nothing special. It's the same difficulty when you switching to dvorak after years of qwerty, or switching to Mac after years of Windows. Basically, it's about changing muscle memory.
The ergonomic-mode minor mode features the command where-is-old-binding, with shortcut “Ctrl+h o”. This command asks you to type a shortcut, and tells you what command it was bound in emacs default, and the new shortcut for it under ErgoEmacs.
For some tips and elisp code for gradual adoption, see: http://code.google.com/p/ergoemacs/wiki/adoption.
On the subject of keyboarding ergonomics, you may wonder if switching from QWERTY to Dvorak provides a better improvement than switching from a lousy to better keyboard shortcut layout. (suppose you chose only one.)
Of my Emacs Commands Frequency study, 43% of key strokes involves data entry (that is, typing and pressing return), while the rest 57% are calling all other commands (moving cursor, deleting chars/words/sentences, formatting, and any emacs command that is not plain typing). 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.
This data suggests that, in editing tasks for programing, a better shortcut placement is probably more important than better placement of letter keys.
For any questions, suggestions, discussions, or announcement of new version, please post or subscribe at http://groups.google.com/group/ergoemacs.
For defect report, enhancement suggestions, please post a issue at http://code.google.com/p/ergoemacs/issues/list.
For some online news mentions and testimonial, see: Testimonial for ErgoEmacs Keybinding.
Much thanks to David Capello, who made this package into a full-featured minor-mode starting with version 5.0.0. (2009-09).
Thanks to many other people who helped in code snippets or suggestions. Please see the package's header for a full list.