11

Is there any way to bind C-[ to something and not have all M- (Meta) bindings messed up?

Not the first time this question comes up. Unfortunately, the only solution offered in the previous thread is a) Linux specific, b) requires an external tool (again Linux specific) that has nothing to do with Emacs. In the same vein I could have used something like Karabiner on a OS X to steal the C-[ sequence before Emacs ever gets it but this is clunky and expensive.

Given that it is Emacs that insists on translating C-[ to ESC, C-i to TAB and probably others I would very much like to break these relationships and get precious key sequences back. Recently I ran full speed into this problem and blamed quiet innocent smartparens mode.

A possible solution that involved function-key-map and key-translation-map was discussed here but alas it either no longer works or did not work in the first place (or I'm doing something wrong). I think it was going in the right direction though.

zeRusski
  • 335
  • 1
  • 8
  • 3
    Emacs does not insist "on translating C-[ to ESC". The two are the same thing. Likewise, C-i and TAB are different names for the same ASCII control code. – Drew Mar 24 '15 at 16:08
  • 3
    @Drew It is not the least bit obvious that key combinations with control must map to ASCII control codes (of which there are only 32) in a GUI application. (Or, heck, even in xterm, which has a modifyOtherKeys mode to send unique escape sequences in many cases, though I'm not sure about these in particular) – Random832 Mar 24 '15 at 19:28
  • 3
    @Random832: You are right to distinguish keys from characters. It is somewhat logical and straightforward for an editor to map the key sequence C-[ (press Ctrl and hit [) to the C-[ control character (aka the ESC character), but no, that is not obligatory for someone designing an editor. And yes, Emacs does that. C-[ and ESC are the same character, but the keys Ctrl + [ and Esc need not be mapped to any particular characters. – Drew Mar 24 '15 at 22:46

1 Answers1

9

Adapted from my own config:

(define-key input-decode-map [?\C-\[] (kbd "<C-[>"))
(global-set-key (kbd "<C-[>") 'butterfly)

This will obviously only work in the GUI.

edit: Note that input-decode-map is terminal-local which means modifying it won't work if you're using emacsclient, but will do if you're using emacs. I've fixed the issue in my config by wrapping it in a command operating on a frame and adding it to the after-make-frame-functions hook.

wasamasa
  • 22,178
  • 1
  • 66
  • 99