I like to use emacs in terminal mode (
-nw), but it seems most (all?) terminals can't handle some key combinations - for example,
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?
I like to use emacs in terminal mode (
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
^M (pronounced “control-emm”), a.k.a. character number 13, a.k.a.
\015). Key combinations involving Alt are typically transmitted as the character
\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
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-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 (
24 for F5 to F12 — for historical reasons, F1 through F4 have different escape sequences) and
number2 indicates the modifier (
2 for Shift,
5 for Ctrl,
3 for Meta,
8 for Ctrl+Meta, and add 1 for +Shift — no, it isn't very consistent).
Emacs translates escape sequences into its internal key representation through
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)])
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.
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.
[27 91 50 55 59 51]to me as opposed to the boring old
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)
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.
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