I like to use emacs in terminal mode (-nw), but it seems most (all?) terminals can't handle some key combinations - for example, C-<RET> or C-M-%. I know this is because most terminals emulate a VT-100, which didn't have these combinations. Are there any linux terminals (preferably KDE) which can handle these key combinations, or is this a fundamental limitation of all terminals?
- 829,060
- 242
4 Answers
When you press a key or key combination in a terminal, it is transmitted to the application running in the terminal as a sequence of one or more characters. For example, when you press a, the application receives a. When you press Enter, the application receives the character CR (a.k.a. ^M (pronounced “control-emm”), a.k.a. character number 13, a.k.a. \r or \015). Key combinations involving Alt are typically transmitted as the character ESC (a.ka. ^[ a.k.a. \e or \033) followed by the sequence for the key or key combination without Alt. Function keys and other key combinations are transmitted as escape sequences beginning with \e[ or \eO.
The escapes sequences are not fully standardized, and terminals typically ignore certain attributes for certain keys. For example, Ctrl+Shift+letter is often transmitted exactly like Ctrl+letter by default.
You can see what your terminal sends for a key combination by pressing Ctrl+V followed by that key combination in a shell prompt, or C-q or C-h c followed by the key combination in Emacs.
With some terminal emulators, you can configure the escape sequences for each key. On Xterm, this is done through X resources. Most setups read resources from ~/.Xresources when X starts, and you can load the file manually with xrdb -merge ~/.Xresources.
Term.VT100.translations: #override \n\
Ctrl ~Shift ~Meta <key>Return: string("\033[73;5~") \n\
Ctrl Shift ~Meta <key>percent: string("\033[37;6~")
A common convention uses escape sequences of the form ESC [ number1 ; number2 ~ for function keys with modifiers. number1 indicates the function key (15 to 24 for F5 to F12 — for historical reasons, F1 through F4 have different escape sequences) and number2 indicates the modifier (2 for Shift, 3 for Meta, 5 for Ctrl, 7 for Ctrl+Meta, and add 1 for Shift with at least one of Ctrl or Meta).
Emacs translates escape sequences into its internal key representation through input-decode-map or local-function-key-map (or function-key-map before Emacs 23).
(define-key local-function-key-map "\033[73;5~" [(control return)])
(define-key local-function-key-map "\033[37;6~" [(control ?L)])
- 829,060
For a limited but significant set of keys, assuming KDE's konsole, one may do the following to have working, complex keybindings in emacs -nw:
I will use my implementation of getting S-<RET> to work as an example:
- Open a new konsole, go to settings -> current profile -> keyboard -> edit
- Hit Add and make a new entry for
Return+Shiftand give it a useful key sequence (I chose\E[27;3which I think is the key sequence sent by X when I was poking around with xev, but that may be wrong -- the important thing to do is make sure that it has a proper escape and doesn't conflict with anything else). - Play with it in the little test area at the bottom to make sure it is working.
- Restart konsole.
Start up
emacs -nwand in the scratch buffer evaluate:(read-key-sequence-vector "Type your new key:")then type your new key combination.
- If you are unfamiliar with this, write the line out, leave the cursor at the end of the line, and hit C-x C-e to get emacs to run that line, it should say to you whatever you put in the quotes and wait for you to type something.
It should spit out a key sequence which you may bind.
(It returned[27 91 50 55 59 51]to me as opposed to the boring old[13]before I messed with the konsole keybinding.)Add to your emacs configuration:
(define-key function-key-map [27 91 50 55 59 51] [(shift return)])I tested it with
emacs -nwin a screen session using:(define-key ess-mode-map [(shift return)] #'ess-eval-line-and-step) (define-key sh-mode-map [(shift return)] #'send-line-to-shell)
There are some efforts of extending the VT protocol in a way to allow lossless keyboard input (among other features, such as graphics).
One example is notty: https://github.com/withoutboats/notty
- 1,696
The short answer is that it is a fundamental limitation of all terminals.
The slightly longer answer is that even if someone created a terminal that does what you want, Emacs itself would require major changes to work with this hypothetical terminal.
- 81
-
That's a good point about emacs, that didn't even occur to me. I guess I'll start using the gui instead. – Yossarian Jun 15 '13 at 08:50
-
infocmp $TERM? – Yossarian Jun 17 '13 at 07:11ESC(unless you want to try some character ≥128, but that will restrict the possible input encodings) and the second character has to be something for which you want noESC foobinding. – Gilles 'SO- stop being evil' Jun 17 '13 at 07:37local-set-keyactually bedefine-key? The former gives an error (wrong number of arguments), while the latter works, at least for C-Enter. It seems konsole still has trouble sending C-M-%. – Yossarian Jun 24 '13 at 12:25define-key. I don't know if Konsole's escape keys can be configured, xterm is probably more customizable than any alternative. – Gilles 'SO- stop being evil' Jun 24 '13 at 14:07XTerm*modifyOtherKeys: 2resource it will generate unique sequences even forC-M-combinations, but with that setting you will need to provide a lot of custom mappings (XTerm*modifyOtherKeys: 1is less capable but far more functional out of the box). For an example (albeit one which didn't work for me) see thexterm-extras.ellibrary and the associated.Xresourcesand.inputrcfiles in the easymacs download. – phils Jun 24 '13 at 22:05^?. Is there any possible way to distinguish between backspace and ctrl+backspace? – trusktr Oct 13 '13 at 15:54