Emacs: Xah Fly Keys Escape Key

By Xah Lee. Date: . Last updated: .

Escape Key in Terminal Problem

🛑 WARNING: there are two different syntax for escape key: <escape> and ESC.

In Emacs 29

;; in emacs 29
;; and when running in terminal, e.g. emacs -nw

;; binding with syntax <escape>, does work
(global-set-key (kbd "<escape>") 'backward-char )
;; and meta key still work
;; e.g. Meta + f for forward-word still work.
;; arrow keys also still work

;; binding with syntax ESC
(global-set-key (kbd "ESC") 'forward-char )
;; but meta key no longer works
;; e.g. Meta + f for forward-word no longer works.
;; but arrow keys still work

Before Emacs 29

Make Escape Key Do Cancel (C-g)

You can make the Escape key do emacs's Ctrl+g. (for cancel. Usually bound to keyboard-quit )

;; make esc key do cancel. works only in gui emacs
(define-key key-translation-map (kbd "<escape>") (kbd "C-g"))

Note: this works 99% of time. When it doesn't, just press Ctrl+g. (the only case i know it doesn't work is when you quit emacs, and emacs says there are unsaved file and if you still want to quit, and pressing Escape to cancel quit doesn't work, but Ctrl+g works.)

Note: for text terminal users, escape key is critical if you do not have Meta key setup. Because Meta+x can be typed by Escape x. So, if you remap Escape, you lose that.

Make Escape Key Do Both Activate Command Mode and Cancel

Make escape key do both activate command mode and cancel. Code by Egor Maltsev

;; make escape key do both activate command mode and cancel
;; from Egor Maltsev
;; Version 2023-04-08 2023-04-09

;; how it works:
;; 1. <escape> set to xah-fly-keys-command-mode-activate in xah-fly-keys-shared-map
;; 2. <escape> set to xah-fly-keys-escape in xah-fly-keys-command-map
;; 3. catched tty ESC translates to <escape>

;; 1. hack escape:

(progn
  (defun xah-fly-keys-escape ()
    (interactive)
    (when (region-active-p)
      (deactivate-mark))
    (when (active-minibuffer-window)
      (abort-recursive-edit)))

  (define-key xah-fly-command-map (kbd "<escape>")     'xah-fly-keys-escape))

(progn
  (defvar xah-fly-keys-fast-keyseq-timeout 200)

  (defun xah-fly-keys-tty-ESC-filter (map)
    (if (and (equal (this-single-command-keys) [?\e])
             (sit-for (/ xah-fly-keys-fast-keyseq-timeout 1000.0)))
        [escape] map))

  (defun xah-fly-keys-lookup-key (map key)
    (catch 'found
      (map-keymap (lambda (k b) (if (equal key k) (throw 'found b))) map)))

  (defun xah-fly-keys-catch-tty-ESC ()
    "Setup key mappings of current terminal to turn a tty's ESC into
`escape'."
    (when (memq (terminal-live-p (frame-terminal)) '(t pc))
      (let ((esc-binding (xah-fly-keys-lookup-key input-decode-map ?\e)))
        (define-key input-decode-map
          [?\e] `(menu-item "" ,esc-binding :filter xah-fly-keys-tty-ESC-filter)))))

  (xah-fly-keys-catch-tty-ESC)

  (define-key key-translation-map (kbd "ESC") (kbd "<escape>")))

;; 2. profit! Escape activates command mode GUI and terminal. Escape
;; activates command mode in minibuffer, second press quits
;; minibuffer. Deactivates mark too

emacs, Xah Fly Keys, customization