Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

On Linux, the Ctrl-[ key combination appears to be equivalent to hitting the Esc key. I would like to define the Ctrl-[ as a shortcut in Emacs but I am unable to because by the time the keystroke gets to Emacs it looks like the Esc key was pressed. Is there anyway to disable this behavior so that Ctrl-[ simply means Ctrl-[?

Running Ubuntu 9.10 with GNOME.

share|improve this question

migrated from stackoverflow.com Aug 9 '10 at 16:22

This question came from our site for professional and enthusiast programmers.

    
Which linux? Which window manager? –  sje397 Aug 9 '10 at 16:18
    
which xterm are you using? –  Nathan Fellman Aug 9 '10 at 17:18

2 Answers 2

Assuming you're running Emacs directly under a windowing system (Cocoa, MS-DOS, Windows, X, ...) and not inside a text terminal (gnome-terminal, konsole, rxvt, xterm, ...), it's possible.

(define-key key-translation-map [?\C-\[] [(control left_bracket)])
(define-key key-translation-map [escape] [?\e])
(define-key function-key-map [escape] nil)
(define-key function-key-map [?\e] nil)
(when (boundp 'local-function-key-map)
  ;;(define-key local-function-key-map [escape] nil)
  (defun remove-escape-from-local-function-key-map ()
    (define-key local-function-key-map [?\e] nil)
    (define-key local-function-key-map [escape] nil))
  (add-hook 'term-setup-hook 'remove-escape-from-local-function-key-map))

There are three different input events at play here:

  • Ctrl+[, i.e., the control modifier together with a key that sends the character [. Emacs would normally show this as C-[ (and C-[ accepted by kbd), if it didn't have a special case for this, as explained below.

  • Character number 27, which is sent by the Esc key on some systems. Emacs shows this as ESC when displaying key sequences, and \e in strings.

  • The Esc key itself (in X Window, this means the Escape keysym). Emacs shows this as escape unless translated (see below).

Emacs normally translates escape into ESC, but this is done at a relatively high level, in function-key-map, so it can be overridden by modifying function-key-map or by defining a binding for escape in the global keymap or a local keymap. GNU Emacs 23 introduces local-function-key-map which applies per terminal type.

Emacs always translates C-[ into ESC, at a very low level (in keyboard.c). This is not configurable.

However Emacs provides a way to translate keys at a relatively low level: key-translation-map. This applies before any global or local binding, but only for keys that are not in function-key-map. So the trick is to exchange ESC and escape at that point.

These mechanisms are described in the Emacs Lisp manual under the heading "Translation keymaps".


By the way, similar principles apply to

  • C-i, TAB, \t tab
  • C-m, RET, \r, return
share|improve this answer

Depending on your xterm, you might be able to use bindkey. Try executing this command at the shell prompt:

bindkey ^] tty-dsusp
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.