Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Do we have a key bindings table that translates all the various ways of referring to a key press? I'm using zsh, but I presume that if there was such a table it would work for any shell.

The reason I ask is that I'd like to assign some keybindings and I have no way of knowing how to refer to them (unless I'm going to steal one that's already defined).

For example, in 'zbindkey' we have this sort of thing:

[[ "$terminfo[kend]"  == " O"* ]] && \
    bindkey -M emacs "${terminfo[kend]/O/[}"  end-of-line

... and I can guess that "kend" means that this refers to the End key.

Cross checking with bindkey I see these lines:

"^E" end-of-line
"^[OF" end-of-line
"^[[F" end-of-line

... so I trust that one of those lines refers to the End key. Which one?

We also have this in the "bindkey" file:

bindkey "\e[A" history-beginning-search-backward

Now, I happen to know that that's the Up Arrow key, but how could I find out if I didn't know?

$ bindkey (at CLI)

... gives us a different language for the same key:

"^[[A" history-beginning-search-backward

... but at least now I know that ^[[A in bindkey-at-CLI speak is the same thing as \e[A in bindkey-in-zbindkey speak. That's easy. In the old days in DOS, the Up Arrow was 0;72 -- you could find the scan code of every legal keystroke and there was only the one language.

Is there a table? Or some other way of being able to pick a keystroke and know how to refer to it in terminfo[] ... in " bindkey-in-zbindkey " ... in "bindkey-at-CLI " and/or in whatever other languages there may happen to be?

Again, in DOS there was the scancode program -- type a keystroke, and you got the scancode. It was sinfully easy.


From the answers I guess then that there is no way to print out a table of all possible bindings? Anyway 'bindkey' does almost what I want:

pts/2 HP-y5-10-Debian1 root /aWorking/Docs $ bindkey -L
bindkey "^@" set-mark-command
bindkey "^A" beginning-of-line
bindkey "^B" backward-char
bindkey "^D" delete-char-or-list
bindkey "^E" end-of-line
...

at least I can see all existing bindings, even if not all possible bindings. Now, if there was just some way of translating the key glyphs into 'regular' terms:

bindkey "Home" beginning-of-line

... then I'd be happy.

share|improve this question
1  
Press Ctrl+V (or whatever stty -a says lnext is) then the key. –  Mikel Feb 23 at 18:51
add comment

3 Answers 3

The interface between a terminal application and a terminal emulator (or hardware terminal) transmits bytes, not keys. Function keys such as cursor movement keys are translated into escape sequences (beginning with the escape character ESC a.k.a. \e a.k.a. \033 a.k.a. 0x1b a.k.a. ^[). The same goes for combinations of a function key or a character key with modifiers, though not all terminals send different sequences for all the different modifier combinations. A few keys are sent encoded as control characters (e.g. Tab → Ctrl-I = \t = \011).

As you can see, there are many ways to describe control characters. Some have a name, corresponding to their traditional function (e.g. Tab, Line feed); those tend to have a backslash+letter combination that you can use inside $'…' or in an argument to echo or print (as well as in sed regular expressions and in string literals in awk, C and other languages (note that different tools may have a slightly different set of escape sequences)). You can use backslash+octal (e.g. \033) in these contexts as well.

There is some variation as to which escape sequence terminals send for each key. Fortunately, there is almost no overlap: there are very few character sequences that mean different keys on different terminal. The main problem is character 127 = \377 = 0x7f which is most often Backspace nowadays but sometimes Delete.

^[OF and ^[[F (i.e. \eOF and \e[F) are the two common escape sequences sent by End. ^E (i.e. \005) is the Emacs key binding (Ctrl+E) for end-of-line.

To see what your terminal emulator sends for a particular key or key combination, press Ctrl+V and then the key in question. This inserts the first character of the escape sequence literally. Escape sequences normally consist of an escape character followed by printable characters, so the rest of the escape sequence is inserted literally too.

The Terminfo database contains the escape sequences for some keys. You'll find the list of Terminfo capabilities in the terminfo(5) man page on your system. In zsh, you can list the values in the database through the terminfo associative array. Beware when printing out values that they contain escape sequences which are also interpreted by the terminal when displayed, so print them in a quoted form.

% print -lr ${(q)terminfo[kend]}
$'\033'OF

See How do keyboard input and text output work? for a more complete overview of what happens when you press a key. It isn't necessary to understand key bindings in zsh.

share|improve this answer
add comment
    BEGINNER'S GUIDE TO ZSH KEYBOARD ASSIGNMENTS, AKA 'KEYBOARD BINDINGS'.

(comments, improvements, bitter denunciations welcome: rayandrews at eastlink dot ca)

'Available' key combinations on a '101' PC keyboard attached to a PC running 'zsh' under xfce4 under Debian Linux (I don't know who's 'in charge'). All combinations that produce duplicate codes within the 'grey' keys have been removed except for the simplest avatar which is shown. Note, some grey keys/combinations have '^letter' duplicates, like 'Enter' == '^M', these have not been removed. Other active combinations were not 'available' since used by the system, even from console, eg. 'Alt+Function' keys switch terminals. Perhaps the 'Meta' key would do more, but this is with a 101 KB. Interesting that there are far more combinations available in DOS, such as Ctrl+Function -- all available in DOS, none of them available in Linux, so it seems. None of the tripple key combinations (eg. 'Ctrl+Alt+Up') produced any unique codes within the grey keys, but they do produce codes in the white keys. Interesting anomalies: '^[[22' '^[[27' '^[[30' are 'missing', you hafta wonder why those numbers were skipped. (Which is to say that you might expect 'F11' to be '^[[22' not '^[[23'.)

The key codes shown are as they would be output by 'showkeys -a' or 'bindkey' at CLI. However, for some reason if you use 'bindkey' within a script (as in '.zshrc') ' ^[ ' must be replaced with ' \e ', thus at CLI:

bindkey -s '^[[[A' 'my-command \C-m'

... bind 'F1' to 'my-command' and execute it (the ' \C-m ' simulates the 'Enter' key).

in '.zshrc':

bindkey -s '\e[25' 'my-command1 ; my command2 \C-m'

... bind 'Shift-F1' to 'my-command1' followed by 'my-command2' and execute both of them.

COMBINATIONS USING JUST THE 'GREY' KEYS:

key[F1] = '^[[[A' key[F2] = '^[[[B' key[F3] = '^[[[C' key[F4] = '^[[[D' key[F5] = '^[[[E' key[F6] = '^[[17~' key[F7] = '^[[18~' key[F8] = '^[[19~' key[F9] = '^[[20~' key[F10] = '^[[21~' key[F11] = '^[[23~' key[F12] = '^[[24~'

key[Shift-F1] = '^[[25~' key[Shift-F2] = '^[[26~' key[Shift-F3] = '^[[28~' key[Shift-F4] = '^[[29~' key[Shift-F5] = '^[[31~' key[Shift-F6] = '^[[32~' key[Shift-F7] = '^[[33~' key[Shift-F8] = '^[[34~'

key[Insert] = '^[[2~' key[Delete] = '^[[3~' key[Home] = '^[[1~' key[End] = '^[[4~' key[PageUp] = '^[[5~' key[PageDown] = '^[[6~' key[Up] = '^[[A' key[Down] = '^[[B' key[Right] = '^[[C' key[Left] = '^[[D'

key[Bksp] = '^?' key[Bksp-Alt] = '^[^?' key[Bksp-Ctrl] = '^H' console only.

key[Esc] = '^[' key[Esc-Alt] = '^[^['

key[Enter] = '^M' key[Enter-Alt] = '^[^M'

key[Tab] = '^I' or '\t' unique form! can be bound, but does not 'showkey -a'. key[Tab-Alt] = '^[\t'

COMBINATIONS USING THE WHITE KEYS:

Anomalies: 'Ctrl+`' == 'Ctrl+2', and 'Ctrl+1' == '1' in xterm. Several 'Ctrl+number' combinations are void at console, but return codes in xterm. OTOH Ctrl+Bksp returns '^H' at console, but is identical to plain 'Bksp' in xterm. There are no doubt more of these little glitches however, in the main:

White key codes are easy to undertand, each of these 'normal' printing keys has six forms:

A = 'a' (duhhh) A-Shift = 'A' (who would have guessed?) A-Alt = '^[a'
A-Ctrl = '^A' A-Alt-Ctrl = '^[^A' A-Alt-Shift = '^[A' A-Ctrl-Shift = '^A' (Shift has no effect)

Don't forget that:

/-Shift-Ctrl = Bksp = '^?' [-Ctrl = Esc = '^[' M-Ctrl = Enter = '^M'

And, we can 'stack' keybindings:

bindkey -s '^Xm' "My mistress\' eyes are nothing like the sun."

... Bind 'Ctrl-X' followed by 'm' to a nice line of poetry.

And we can flirt with madness:

bindkey -s '^Pletmenot' 'Let me not, to the marriage of true minds'

... but you hafta start something like that with a 'modifier' character. Try it, if you like keyboard shortcuts, you can really go to town.

QUESTIONS:

Where is it written that 'Ctrl-Bksp' means one thing at console, another thing in xterm?

Are these assignments changable?

Who designed all this, and what were they thinking at the time?

Why is it 'Alt-Function' to change terminals at a terminal, but 'Alt-Ctrl-Function' to change to a terminal from GUI?

How/where is 'Alt-Ctrl-Delete' defined?

enter code here
share|improve this answer
add comment

There are many tools at your disposal in Unix/Linux so it can be bit confusing and overwhelming. For starters I'd use showkey:

$ showkey -a

Press any keys - Ctrl-D will terminate this program

a    97 0141 0x61
b    98 0142 0x62
c    99 0143 0x63
d   100 0144 0x64
e   101 0145 0x65
f   102 0146 0x66
g   103 0147 0x67

From the man page regarding -a:

   When  in  `ascii' dump mode, showkey prints to the standard output the 
   decimal, octal, and hexadecimal value(s) of the key pressed,
   according to he present keymap.

You can use xmodmap to get some of the mappings:

$ xmodmap
xmodmap:  up to 4 keys per modifier, (keycodes in parentheses):

shift       Shift_L (0x32),  Shift_R (0x3e)
lock        Caps_Lock (0x42)
control     Control_L (0x25),  Control_R (0x69)
mod1        Alt_L (0x40),  Alt_R (0x6c),  Meta_L (0xcd)
mod2        Num_Lock (0x4d)
mod3      
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)
mod5        ISO_Level3_Shift (0x5c),  Mode_switch (0xcb)

The above isn't all of the pieces to the puzzle but is some additional info that might be helpful towards you finding the ultimate map between the keybindings and the scancodes. There is more info in this U&L Q&A titled: Key mappings in Linux.

References

share|improve this answer
    
While this is all true, it's irrelevant to understanding key bindings in a terminal. –  Gilles Feb 24 at 0:39
    
@Gilles - yeah I kind of figured that, I was only attempting to provide leads, now that I've read your A I understand how that interface works, thanks! –  slm Feb 24 at 1:01
add comment

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.