12

I'd like to use the ESC key instead of C-g for keyboard-quit. My naïve approach to just do

(define-key global-map (kbd "ESC") 'keyboard-quit)

does not work. ESC is still a prefix key and pressing it does not call keyboard-quit.

Geier
  • 692
  • 5
  • 15
  • 1
    You may interested in this related thread - I used that solution for about a year until I got used to C-g and ESC-ESC-ESC: **How to use (conditionally) as a modifier key** http://stackoverflow.com/a/20036348/2112489 The answer by Stefan in that related thread is the same concept that used by the `universal-argument` with the `universal-argument-map`. – lawlist Aug 14 '15 at 22:03

4 Answers4

12

You can do (define-key key-translation-map (kbd "ESC") (kbd "C-g")). I did the same a long time ago and had no problems.

Edit to improve the answer according to the comments:

If you want to keep the ESC key functionality, you can do

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

One thing to note is that if Emacs hangs you still have to use the C-g key for some reason, but that happens rarely.

clemera
  • 3,401
  • 13
  • 40
  • This is an incomplete solution because there is no replacement for the original ESC key functionality. ESC is a special key that large parts of Emacs interaction depends on. – Emacs User Aug 15 '15 at 02:47
  • 1
    @EmacsUser Even if I never hit ESC while using emacs? – Geier Aug 15 '15 at 05:35
  • Yes, try ESC once, twice, and three times to see how it invokes a different command. – Emacs User Aug 15 '15 at 05:40
  • 1
    @EmacsUser: So? As of now, I never press ESC once, let alone twice or three times. I'm not going to miss it. – Geier Aug 15 '15 at 05:46
  • Then go ahead. When you are stuck in a loop and cannot exit, you can come back and re-read this advice. – Emacs User Aug 15 '15 at 05:51
  • 2
    @EmacsUser I'm not saying that this is the correct answer and that I want to use it, I just want to understand what's wrong with it. The whole "in the future, you won't be able to press ESC twice" doesn't affect me at all. If you tell me under what conditions I might get into an infinite loop with this and why, that would be really insightful. – Geier Aug 15 '15 at 06:23
  • 1
    @Geier I used this remapping for a long time and never have encountered any problems with it. The only thing is that if emacs hangs you have to press `C-g` to unhang it, the `ESC` remapping dosn't work in this case. – clemera Aug 15 '15 at 10:00
  • 2
    @EmacsUser I never had a use case for `ESC` so this didn't bother me. But if you need it you can do another translation, for example `(define-key key-translation-map (kbd "C-") (kbd "ESC"))` – clemera Aug 15 '15 at 10:11
9

My advice would be to leave ESC alone, because it is a special key.

By default, Emacs uses ESC (ASCII 27) as the meta-prefix-key. From the Elisp Manual:

‘esc-map’ is the global keymap for the prefix key. Thus, the global definitions of all meta characters are actually found here. This map is also the function definition of ‘ESC-prefix’.

and

Instead, meta characters are regarded for purposes of key lookup as sequences of two characters, the first of which is ESC (or whatever is currently the value of ‘meta-prefix-char’). Thus, the key ‘M-a’ is internally represented as ‘ESC a’, and its global binding is found at the slot for ‘a’ in ‘esc-map’.

So to use ESC for something else you would need to set meta-pefix-key to something else, and also bind some other key to ESC-prefix. There may be other changes required as well -- I've never tried this.

For more on meta-prefix-char, see Functions for Key Lookup in the Elisp manual.

glucas
  • 20,175
  • 1
  • 51
  • 83
  • 1
    +1. Do *not* remove the binding of `ESC`. Bind another key to `keyboard-quit`, if you like. And be aware that **`ESC ESC ESC`** already gives you the escape behavior you want -- see the Emacs manual, node [Quitting](http://www.gnu.org/software/emacs/manual/html_node/emacs/Quitting.html). – Drew Aug 14 '15 at 21:08
  • 2
    Setting the `meta-prefix-char` to `nil` on OSX will *not* disable it from being a prefix key -- it will only separate it from the meta key. On OSX with a graphical version of Emacs, I like to have the escape key separated from the meta key -- I set `(setq meta-prefix-char nil)` at the outset of my initialization so that all subsequently loaded libraries understand that is what I want. This gives me the ability to use the meta key as prefix key, and the escape key as a prefix key. The `esc-map` is defined at the C-source code level within `keymap.c`. It is meant to be used as a prefix key. – lawlist Aug 14 '15 at 21:56
  • @lawlist Interesting - so do you then map meta to be the `esc-map` prefix to preserve the default M- bindings? – glucas Aug 14 '15 at 22:15
  • I think this is the relevant setting on OSX: `(setq ns-alternate-modifier 'meta)`, which makes meta the left alt key on the Apple keyboard. I like to use the right alt key to create unicode characters using OSX default settings: `(setq ns-right-alternate-modifier 'none)` -- to insert Spanish characters, paragraph symbols, etc. When building `--with-ns`, both the left and right alt keys are set to meta. The default setting ties the escape key to the meta key on OSX using the `meta-prefix-char`, which is `27` as you stated. – lawlist Aug 14 '15 at 22:48
  • 8
    Use emacs, they say. It's extensible, they say. You don't have to adjust to it, it adjusts to you, they say. That is, it only adjusts to you if you like to escape a situation by pressing ESC three times. Because someone in the past thought that ESC is such a unheard-of key (it's only on the top left corner of every keyboard) that he better tie it up with the Meta key :-( . – Geier Aug 15 '15 at 05:42
  • Actually, this appears to work for me: `(global-set-key (kbd "") #'keyboard-escape-quit)`. If I bind to `(kbd "ESC")` instead, all the meta bindings stop working. You mileage may vary depending on OS, GUI vs. terminal Emacs, etc. – glucas Aug 15 '15 at 12:08
1

Lovely answer over here: https://superuser.com/a/945245/624661

Quoting:

You can use this in your Emacs init file:

;;; esc always quits
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit)
(global-set-key [escape] 'keyboard-quit)
Ole
  • 131
  • 6
1

You want to bind [escape], not (kbd "ESC"), as the bindings referenced by Ole show. In stock, this will work only if emacs frames in a window system. I think this is worth a bit of explanation.

(kdb "ESC") means actually the ASCII control character ESC, and as glucas mentioned, you certainly don't want to remap this one. But Esc is not ASCII ESC: it is symbol escape, at least in a graphical environment. How does it occur that binding (kbd "ESC") affects Esc then? This happens because emacs translates escape to ESC if there is no available binding for escape. Kind of a fallback if you wish (which is implemented by the means of local-function-key-map if you're interested in such things).

Thus, when you bind [escape], you're safe and don't have to worry about ESC; apart from your own bindings, you just have to augment the keymaps that say ESC when they mean [escape].

Hmm... well, almost. Why don't these maps use [escape] at the first time? Because this won't work in a terminal. If you want your Esc work on a such a device, you'll have at the very least to customize your terminal before.

The story of the terminal is reported in another post: How to bind C-[ for real?. What you have to do is tell the terminal to send some custom sequence when Esc is pressed, then map this sequence to [escape] at an early input stage in emacs (the input-decode-map).

Hope this helps.

Champignac
  • 231
  • 2
  • 6