The Roadmap to Completely Replace Emacs Key System, Part 2

By Xah Lee. Date: . Last updated: .

This page discusses a systematic way to replace emacs's one thousand keys.

about 6 months ago, i discovered that key sequence (e.g. Alt Space, F7 F7) is far better than key chords (e.g. Ctrl+x, Alt+x ), and started to get rid of key chords in my emacs. See: The Roadmap to Completely Replace Emacs Key System. Now, i report the current status and design of this system.

now, i have a entire system to replace emacs 1000 default keybinding, and efficient, and very satisfactory to me. [see A Curious Look at Emacs One Thousand Keybindings]

this system, makes emacs keys compatible with all other software on {Windows, Mac, Linux}. e.g. {open, close, cut, copy, undo, etc} about 9 keys are the same. (this is already true of ErgoEmacs Keybinding)

yet, for all other thousand keys, it's much more efficient. It's even beyond ErgoEmacs. I'm currently not sure it'll be part of future ErgoEmacs, because it's rather radical. It's only for those who diddle with keys a lot. (e.g. you use Dvorak users, heavy AutoHotkey users, or heavy diddler of Linux Window Manager or other key tools.)

this system relies on key sequences. So, all commands, is just pressing no more than 3 keys, no key chord as part of it, not even Shift key (so, there'd be no key involving {%, !}, for example.). Just 3 one-finger keys. Key choices are based on command call frequency and key ease position. The starting, activation key (what emacs calls “prefix key”), is critical. It must be a most easy key. Example of such keys are: CapsLock, Alt, ▤ Menu, or even Space bar (that'd be best if possible). The ▤ Menu as activation key can be easily done in emacs across OSes, but for other you'll need a tool outside of emacs.

Right now, the issue is the exact choice of keys for emacs's thousands of commands. This i haven't got down yet, but, for myself, i've been on this road for about half a year now, and have sketched out a map of about 200 commands, especially pushed further by having the Truly Ergonomic Keyboard hardware few weeks ago. It's supreme!

from 1998 to 2005, i use GNU Emacs in terminal only, all default keys. But today, the default key i use in emacs is about maybe 6, and 4 of them being the arrow keys, one Backspace ⌫. The other one is F1. Maybe about 2 mode-specific C-c ones.

i think i'll talk to David Capello [] and Matthew L Fidler soon about making this into part of ErgoEmacs, but will ask them what they think first, have them use it and convinced it's real good, because it's rather radical. (if we integrate it into ErgoEmacs, am pretty sure it'll be optional, and off by default)

In summary:

here's a sample of implementation, my current setup, to illustrate the idea. The choice of keys is actually in flux, and i have yet to exam the default thousand keys and think what key each of them should be. For my own emacs use daily, i've been using this for about half a year now, and tweaking keys daily.

;; -*- coding: utf-8 -*-
;; 2013-01-31
;; generic

(define-key key-translation-map (kbd "<apps>") (kbd "<menu>"))
(define-key key-translation-map (kbd "<f6>") (kbd "<menu>")) ; F6 is fall back

(define-prefix-command 'xah-keymap)
(global-set-key (kbd "<menu>") xah-keymap)

;; Truly Ergonomic keyboard + Dvorak layout
;; \` 1234 5 6 7890 []
;; \z ',.p y f gcrl /=
;;    aoeu i d htns
;;    ;qjk x b mwv-

;; prefix keys (on Dvorak) should be
;; .p gc
;; eu ht

;; u is for unicode insert
;; e is mode-specific
;; h is help-map
;; t is generic dump space
;; x is for ctl-x-map

;; add find-file
;; keyboard-quit

;; stars indicate frequency of use
;; ★★★ every minute
;; ★★ every hour
;; ★ few times a day

(global-set-key (kbd "<menu> <return>") 'smex)
(global-set-key (kbd "<menu> <delete>") 'delete-current-file)
(global-set-key (kbd "<menu> <f2>") 'ergoemacs-cut-all)
(global-set-key (kbd "<menu> <f3>") 'ergoemacs-copy-all)

(global-set-key (kbd "<menu> '") 'nil)
(global-set-key (kbd "<menu> ,") 'shell-command-on-region)
(global-set-key (kbd "<menu> -") 'xc-comment-smart) ; ★★★ , comment-dwim
(global-set-key (kbd "<menu> .") 'shell-command)   ; ★★★

(global-set-key (kbd "<menu> /") 'nil)
(global-set-key (kbd "<menu> 0") 'delete-window)
(global-set-key (kbd "<menu> 1") 'copy-to-register-1)
(global-set-key (kbd "<menu> 2") 'paste-from-register-1)
(global-set-key (kbd "<menu> 3") 'delete-other-windows) ; ★★★
(global-set-key (kbd "<menu> 4") 'split-window-vertically) ; ★★★
(global-set-key (kbd "<menu> 5") 'nil) ; ★★★
(global-set-key (kbd "<menu> 6") 'xah-run-current-file) ;; immediate, but dangerous eval-buffer
(global-set-key (kbd "<menu> 7") 'xah-open-file-at-cursor) ; ★★★ find-file-at-point
(global-set-key (kbd "<menu> 8") 'dired-jump)              ; ★★★
(global-set-key (kbd "<menu> 9") 'ispell-word) ; ★★★
(global-set-key (kbd "<menu> ;") 'nil)
(global-set-key (kbd "<menu> =") 'nil)
(global-set-key (kbd "<menu> SPC") 'set-mark-command) ; ★★★
(global-set-key (kbd "<menu> [") 'remove-square-brackets)
(global-set-key (kbd "<menu> \\") 'escape-quotes)
(global-set-key (kbd "<menu> ]") 'indent-region)
(global-set-key (kbd "<menu> `") 'make-backup)
(global-set-key (kbd "<menu> a") 'mark-whole-buffer) ; ★★
(global-set-key (kbd "<menu> b") 'flyspell-buffer) ; ★★
(global-set-key (kbd "<menu> c") 'nil)
(global-set-key (kbd "<menu> d") 'ergoemacs-open-in-desktop)
(global-set-key (kbd "<menu> e") 'nil)  ; mode specific
(global-set-key (kbd "<menu> f") 'copy-file-path)

(global-set-key (kbd "<menu> g 0") ")")
(global-set-key (kbd "<menu> g 1") "!")
(global-set-key (kbd "<menu> g 2") "@")
(global-set-key (kbd "<menu> g 3") "#")
(global-set-key (kbd "<menu> g 4") "$")
(global-set-key (kbd "<menu> g 5") "%")
(global-set-key (kbd "<menu> g 6") "^")
(global-set-key (kbd "<menu> g 7") "&")
(global-set-key (kbd "<menu> g 8") "*")
(global-set-key (kbd "<menu> g 9") "(")
(global-set-key (kbd "<menu> g a") "A")
(global-set-key (kbd "<menu> g b") "B")
(global-set-key (kbd "<menu> g c") "C")
(global-set-key (kbd "<menu> g d") "D")
(global-set-key (kbd "<menu> g e") "E")
(global-set-key (kbd "<menu> g f") "F")
(global-set-key (kbd "<menu> g g") "G")
(global-set-key (kbd "<menu> g h") "H")
(global-set-key (kbd "<menu> g i") "I")
(global-set-key (kbd "<menu> g j") "J")
(global-set-key (kbd "<menu> g k") "K")
(global-set-key (kbd "<menu> g l") "L")
(global-set-key (kbd "<menu> g m") "M")
(global-set-key (kbd "<menu> g n") "N")
(global-set-key (kbd "<menu> g o") "O")
(global-set-key (kbd "<menu> g p") "P")
(global-set-key (kbd "<menu> g q") "Q")
(global-set-key (kbd "<menu> g r") "R")
(global-set-key (kbd "<menu> g s") "S")
(global-set-key (kbd "<menu> g t") "T")
(global-set-key (kbd "<menu> g u") "U")
(global-set-key (kbd "<menu> g v") "V")
(global-set-key (kbd "<menu> g w") "W")
(global-set-key (kbd "<menu> g x") "X")
(global-set-key (kbd "<menu> g y") "Y")
(global-set-key (kbd "<menu> g z") "Z")

(global-set-key (kbd "<menu> h") help-map) ; ★★★
(global-set-key (kbd "<menu> i d") 'insert-date)
(global-set-key (kbd "<menu> i r h") 'insert-random-hex)
(global-set-key (kbd "<menu> i r n") 'insert-random-number)
(global-set-key (kbd "<menu> i r s") 'insert-random-string)
(global-set-key (kbd "<menu> i r u") 'insert-random-uuid)
(global-set-key (kbd "<menu> i t") 'insert-date-time)
(global-set-key (kbd "<menu> j") 'nil)
(global-set-key (kbd "<menu> k") 'nil)
(global-set-key (kbd "<menu> l") 'recenter-top-bottom)
(global-set-key (kbd "<menu> m c") 'calc)
(global-set-key (kbd "<menu> m e") 'emacs-lisp-mode)
(global-set-key (kbd "<menu> m h") 'xah-html-mode)
(global-set-key (kbd "<menu> m l") 'linum-mode)
(global-set-key (kbd "<menu> m s") 'shell)
(global-set-key (kbd "<menu> m t") 'text-mode)
(global-set-key (kbd "<menu> m v") 'visual-line-mode)
(global-set-key (kbd "<menu> m w") 'whitespace-mode)
(global-set-key (kbd "<menu> n") 'ergoemacs-new-empty-buffer) ; ★★★
(global-set-key (kbd "<menu> o SPC") 'xah-open-file-fast)
(global-set-key (kbd "<menu> o b") 'ibuffer)
(global-set-key (kbd "<menu> o f") 'ido-find-file)
(global-set-key (kbd "<menu> o l") 'bookmark-bmenu-list)
(global-set-key (kbd "<menu> o r") 'recentf-open-files) ; ★★★
(global-set-key (kbd "<menu> o s") 'ido-switch-buffer)  ; ★★★
(global-set-key (kbd "<menu> p") 'nil)
(global-set-key (kbd "<menu> q") 'quoted-insert) ; ★★★
(global-set-key (kbd "<menu> r '") 'replace-straight-quotes)
(global-set-key (kbd "<menu> r ,") 'xah-remove-punctuation-trailing-redundant-space)
(global-set-key (kbd "<menu> r .") 'xah-convert-english-chinese-punctuation)
(global-set-key (kbd "<menu> r d") 'delete-matching-lines) ; ★★
(global-set-key (kbd "<menu> r e") 'query-replace) ; ★★★
(global-set-key (kbd "<menu> r f") 'xah-find-text)
(global-set-key (kbd "<menu> r l") 'list-matching-lines) ; ★★★
(global-set-key (kbd "<menu> r p") 'convert-ideographic/ascii-space)
(global-set-key (kbd "<menu> r r") 'xah-find-replace-text)
(global-set-key (kbd "<menu> r u") 'query-replace-regexp)
(global-set-key (kbd "<menu> s") 'save-buffer) ; ★★★
(global-set-key (kbd "<menu> t c") 'xah-cite)
(global-set-key (kbd "<menu> t f") 'xah-open-file-from-clipboard)
(global-set-key (kbd "<menu> t l") 'xah-clean-whitespace)
(global-set-key (kbd "<menu> t n") 'make-frame-command)
(global-set-key (kbd "<menu> t o") 'ergoemacs-open-last-closed)
(global-set-key (kbd "<menu> t r") 'repeat-complex-command)
(global-set-key (kbd "<menu> t s") 'title-case-string-region-or-line)
(global-set-key (kbd "<menu> t w") 'delete-trailing-whitespace)

(global-set-key (kbd "<menu> u -") "—") ; EM DASH
(global-set-key (kbd "<menu> u .") "…") ; HORIZONTAL ELLIPSIS
(global-set-key (kbd "<menu> u 4") "◆") ; black diamond
(global-set-key (kbd "<menu> u 7") "&") ; full width ampersand
(global-set-key (kbd "<menu> u 8") "•") ; bullet
(global-set-key (kbd "<menu> u <S-right>") "⇒")
(global-set-key (kbd "<menu> u <right>") "→")
(global-set-key (kbd "<menu> u B") 'insert-pair-white-lenticular-bracket〖〗)
(global-set-key (kbd "<menu> u M") 'insert-pair-white-corner-bracket『』)
(global-set-key (kbd "<menu> u W") 'insert-pair-double-angle-bracket《》)
(global-set-key (kbd "<menu> u \\") "、") ; IDEOGRAPHIC COMMA
(global-set-key (kbd "<menu> u b") 'insert-pair-black-lenticular-bracket【】)
(global-set-key (kbd "<menu> u c") "=") ; equal
(global-set-key (kbd "<menu> u f") 'insert-pair-single-straight-quote)
(global-set-key (kbd "<menu> u g") 'insert-pair-double-straight-quote)
(global-set-key (kbd "<menu> u h") 'insert-pair-brace)              ;{}
(global-set-key (kbd "<menu> u i") 'insert-pair-single-curly-quote‘’)
(global-set-key (kbd "<menu> u m") 'insert-pair-corner-bracket「」)
(global-set-key (kbd "<menu> u n") 'insert-pair-bracket)            ;[]
(global-set-key (kbd "<menu> u p") 'insert-pair-double-angle-quote«»)
(global-set-key (kbd "<menu> u r") "+") ; plus
(global-set-key (kbd "<menu> u t") 'insert-pair-paren)              ;()
(global-set-key (kbd "<menu> u u") 'insert-pair-double-curly-quote“”)
(global-set-key (kbd "<menu> u w") 'insert-pair-angle-bracket〈〉)
(global-set-key (kbd "<menu> u x") 'insert-pair-tortoise-shell-bracket〔〕)
(global-set-key (kbd "<menu> u y") 'insert-pair-single-angle-quote‹›)

(global-set-key (kbd "<menu> v") 'nil)
(global-set-key (kbd "<menu> w") 'ergoemacs-close-current-buffer) ; ★★★
(global-set-key (kbd "<menu> x") ctl-x-map) ; ★★★
(global-set-key (kbd "<menu> y") 'universal-argument) ; ★★
(global-set-key (kbd "<menu> z") 'nil)

(define-key help-map (kbd "c") 'describe-char)
(define-key help-map (kbd "5") 'man)
(define-key help-map (kbd "7") 'xah-lookup-google)
(define-key help-map (kbd "8") 'xah-lookup-wikipedia)
(define-key help-map (kbd "9") 'xah-lookup-word-definition)
(define-key help-map (kbd "`") 'elisp-index-search)
(define-key help-map (kbd "m") 'ergoemacs-describe-major-mode)
(define-key help-map (kbd "o") 'nil)  ; ergoemacs-where-is-old-binding
(define-key help-map (kbd "h") 'nil) ; view-hello-file

;; example of mode-specific setting

(defun xah-html-mode-keys ()
  "Modify keymaps used by `html-mode'."
  ;; .p gc
  ;; eu ht

  (local-set-key (kbd "<menu> e .") 'xah-browse-url-of-buffer)
  (local-set-key (kbd "<menu> e 0") 'xah-html-remove-html-tags)
  (local-set-key (kbd "<menu> e 5") 'mark-unicode)
  (local-set-key (kbd "<menu> e 7") 'htmlize-or-dehtmlize-pre-block)
  (local-set-key (kbd "<menu> e 8") 'get-pre-block-make-new-file)
  (local-set-key (kbd "<menu> e <delete>") 'sgml-delete-tag)
  (local-set-key (kbd "<menu> e <left>") 'sgml-skip-tag-backward)
  (local-set-key (kbd "<menu> e <right>") 'sgml-skip-tag-forward)
  (local-set-key (kbd "<menu> e a") 'xwe-annotate)
  (local-set-key (kbd "<menu> e b") 'make-blogger-entry)
  (local-set-key (kbd "<menu> e c") 'xah-html-make-citation)
  (local-set-key (kbd "<menu> e d") 'insert-date-tag)
  (local-set-key (kbd "<menu> e e") 'xah-html-wrap-html-tag)
  (local-set-key (kbd "<menu> e f") 'xah-copy-url-current-file)
  (local-set-key (kbd "<menu> e k") 'xah-html-htmlize-keyboard-shortcut-notation)
  (local-set-key (kbd "<menu> e l 6") 'xah-html-source-url-linkify)
  (local-set-key (kbd "<menu> e l c") 'xwe-chinese-linkify)
  (local-set-key (kbd "<menu> e l d") 'perldoc-ref-linkify)
  (local-set-key (kbd "<menu> e l e") 'emacs-ref-linkify)
  (local-set-key (kbd "<menu> e l f") 'full-size-img-linkify)
  (local-set-key (kbd "<menu> e l i") 'image-linkify)
  (local-set-key (kbd "<menu> e l j") 'image-file-to-html-figure-tag)
  (local-set-key (kbd "<menu> e l l") 'xah-html-lines-to-list)
  (local-set-key (kbd "<menu> e l p") 'php-ref-linkify)
  (local-set-key (kbd "<menu> e l t") 'xwe-word-etymology-linkify)
  (local-set-key (kbd "<menu> e l u") 'xah-html-wrap-url)
  (local-set-key (kbd "<menu> e l w") 'xah-html-wikipedia-linkify)
  (local-set-key (kbd "<menu> e l z") 'amazon-linkify)
  (local-set-key (kbd "<menu> e m a") 'xah-make-atom-entry)
  (local-set-key (kbd "<menu> e m l") 'xah-add-to-related-links)
  (local-set-key (kbd "<menu> e p") 'xah-html-wrap-p-tag)
  (local-set-key (kbd "<menu> e r ,") 'xah-html-escape-char-to-unicode)
  (local-set-key (kbd "<menu> e r .") 'xah-html-escape-char-to-entity)
  (local-set-key (kbd "<menu> e r 3") 'xah-html-update-title)
  (local-set-key (kbd "<menu> e r 4") 'xahsite-update-article-timestamp)
  (local-set-key (kbd "<menu> e r c") 'code-bracket-to-html-tag)
  (local-set-key (kbd "<menu> e r e") 'curly-quotes-to-emacs-function-tag)
  (local-set-key (kbd "<menu> e r k") 'emacs-to-windows-kbd-notation)
  (local-set-key (kbd "<menu> e r m") 'xah-html-lines-to-table)
  (local-set-key (kbd "<menu> e r t") 'title-bracket-to-html-tag)
  (local-set-key (kbd "<menu> e t c") 'insert-random-color-hsl)
  (local-set-key (kbd "<menu> e t r") 'xah-html-rename-html-inline-image)
  (local-set-key (kbd "<menu> e t u") 'xah-html-extract-url)
  (local-set-key (kbd "<menu> e u") 'xah-all-linkify)

(add-hook 'html-mode-hook 'xah-html-mode-keys)
(add-hook 'xah-html-mode-hook 'xah-html-mode-keys)


for update, see The Roadmap to Completely Replace Emacs Key System, Part 2.5

The Roadmap to Completely Replace Emacs Key System