24

I was reading this message from the zsh mailing list about key bindings and I'd like to know which key I need to press:

  1. ^X^I (I think Ctrl-X Ctrl-I, the capital X and I)
  2. ^[^@ (I think Ctrl-Esc-@ ??)
  3. ^X^[q(I think Ctrl-X Esc-q ??)
  4. ^XQ (I think Ctrl-X and Q ??)

From the Archlinux wiki page on zsh

  1. ^[[1;3A
  2. ^[[1;3D

From bindkey

  1. ^[[1;5C
  2. ^[[A

I know that ^[ means Esc, but I'm not sure how to find others. Is there any official reference or website that lists these?

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
shin
  • 749
  • 1
    ^[^@ = Control-Alt-Space, provided that your terminal sends ^[ => Esc when you press Meta = Alt. This is a whole fatuous vapid pretentious mess, also subject to runtime configurations (go read about the *SendsEscape options in the xterm manpage). Most (but not all!) "functional" key escapes can be gathered from the output of infocmp and the terminfo(5) manpage (eg. infocmp xterm | fgrep '\E[1;2H' => kHOM, with kHOM being defined as shifted home key in the manpage. For the rest (e.g. Ctrl-Left => ^[[1;5C), you'll have to work it out from ctlseqs.txt and the source code. –  Jan 18 '21 at 06:37
  • 3
    @user414777 how it is fatuous, vapid, or pretentious? – OrangeDog Jan 18 '21 at 13:12
  • 3
    @OrangeDog If after reading the xterm manpage you're able to understand the purpose of altIsNotMeta, altSendsEscape, metaSendsEscape, eightBitInput and map out the perverse interactions between them, then good to you -- but have a little mercy and patience with those less fortunate than you, like me. –  Jan 18 '21 at 17:37
  • 1
    As a note, you so not need to specifically indicate "uppercase" X and I; for historical reasons, Ctrl treats upper and lower as identical. – chrylis -cautiouslyoptimistic- Jan 19 '21 at 08:17

3 Answers3

25

^c is a common notation for Ctrl+c where c is a (uppercase) letter or one of @[\]^_. It designates the corresponding control character. The correspondence is that the numeric code of the control character is the numeric code of the printable character (letter or punctuation symbol) minus 64, which corresponds to setting a bit to 0 in base 2. In addition, ^? often means character 127.

Some keys send a control character:

  • Escape = Ctrl+[
  • Tab = Ctrl+I
  • Return (or Enter or ) = Ctrl+M
  • Backspace = Ctrl+? or Ctrl+H (depending on the terminal configuration)

Alt (often called Meta because that was the name of the key at that position on historical Unix machines) plus a printable character sends ^[ (escape) followed by that character.

Most function and cursor keys send an escape sequence, i.e. the character ^[ followed by some printable characters. The details depend on the terminal and its configuration. For xterm, the defaults are documented in the manual. The manual is not beginner-friendly. Here are some tips to help:

  • CSI means ^[[, i.e. escape followed by open-bracket.
  • SS3 means ^[O, i.e. escape followed by uppercase-O.
  • "application mode" is something that full-screen programs usually turn on. Some keys send a different escape sequence in this mode, for historical reasons. (There are actually multiple modes but I won't go into a detailed discussion because in practice, if it matters, you can just bind the escape sequences of both modes, since there are no conflicts.)
  • Modifiers (Shift, Ctrl, Alt/Meta) are indicated by a numerical code. Insert a semicolon and that number just before the last character of the escape sequence. Taking the example in the documentation: F5 sends ^[[15~, and Shift+F5 sends ^[[15;2~. For cursor keys that send ^[[ and one letter X, to indicate a modifier M, the escape sequence is ^[[1;MX.

Xterm follows an ANSI standard which itself is based on historical usage dating back from physical terminals. Most modern terminal emulators follow that ANSI standard and implement some but not all of xterm's extensions. Do expect minor variations between terminals though.

Thus:

  • ^X^I = Ctrl+X Ctrl+I = Ctrl+X Tab
  • ^[^@ = Ctrl+Alt+@ = Escape Ctrl+@. On most terminals, Ctrl+Space also sends ^@ so ^[^@ = Ctrl+Alt+Space = Escape Ctrl+Space.
  • ^X^[q = Ctrl+X Alt+q = Ctrl+X Escape q
  • ^XQ = Ctrl+X Shift+q
  • ^[[A = Up
  • ^[[1;3A = Alt+Up (Up, with 1;M to indicate the modifier M). Note that many terminals don't actually send these escape sequences for Alt+cursor key.
  • ^[[1;3D = Alt+Left
  • ^[[1;5C = Ctrl+Right

There's no general, convenient way to look up the key corresponding to an escape sequence. The other way round, pressing Ctrl+V followed by a key chord at a shell prompt (or in many terminal-based editors) inserts the escape sequence literally.

See also How do keyboard input and text output work? and key bindings table?

  • 2
    Instead of "numeric code - 64" --with ^? "often" being a curious & unexplained exception -- how about the "numeric code xor 64"? As it was already defined in the SysV source code since 40 years ago. –  Jan 18 '21 at 06:05
  • 1
    @user414777 subtraction is a familiar concept, xor isn't. And I think I've seen more software implement it as (if 63 then 127 else if 64..95 then x-64 else error) than (xor 64). – Gilles 'SO- stop being evil' Jan 18 '21 at 12:49
  • 1
    "Some keys send a control character" - that's probably not the actual keyboard sending. You likely have an USB keyboard today, which uses the USB HID standard. These "key bindings" happen later in the console I/O processing – MSalters Jan 18 '21 at 15:11
  • 2
    @MSalters The terminal emulator (or terminal driver if you aren't using a GUI) does this translation. The translation would only be done in a separate piece of hardware if you were using an actual serial terminal, which in the 21st century is very uncommon. See How do keyboard input and text output work? – Gilles 'SO- stop being evil' Jan 18 '21 at 16:34
  • 2
    Toggling a bit is not an arcane concept, by any stretch. –  Jan 18 '21 at 17:40
  • 2
    @user414777 although it isn't, many modern programmers don't even know what bitwise operations do, let alone non-programmers. At the same time, basic arithmetic is known by virtually anyone. But indeed, I'd really like to see the xor formulation of the conversion in this answer, maybe in a footnote. – Ruslan Jan 19 '21 at 00:35
  • 2
    ^c was a common notation for Ctrl-C. Now only old nerds use it... – RonJohn Jan 19 '21 at 04:29
  • 1
    I hope you had a keyboard macro to add all of the <kbd> tags in your answer! – Mark Stewart Jan 19 '21 at 19:26
5

To extend on Gilles' mention of the correspondence:

The correspondence is that the numeric code of the control character is the numeric code of the printable character (letter or punctuation symbol) minus 64, which corresponds to setting a bit to 0 in base 2.

You can see it in ascii(7). Look at the octal numbers:

Oct   Dec   Hex   Char                        Oct   Dec   Hex   Char
────────────────────────────────────────────────────────────────────────
000   0     00    NUL '\0' (null character)   100   64    40    @
001   1     01    SOH (start of heading)      101   65    41    A
002   2     02    STX (start of text)         102   66    42    B
003   3     03    ETX (end of text)           103   67    43    C
004   4     04    EOT (end of transmission)   104   68    44    D
005   5     05    ENQ (enquiry)               105   69    45    E
006   6     06    ACK (acknowledge)           106   70    46    F
007   7     07    BEL '\a' (bell)             107   71    47    G
010   8     08    BS  '\b' (backspace)        110   72    48    H
011   9     09    HT  '\t' (horizontal tab)   111   73    49    I
012   10    0A    LF  '\n' (new line)         112   74    4A    J
013   11    0B    VT  '\v' (vertical tab)     113   75    4B    K
014   12    0C    FF  '\f' (form feed)        114   76    4C    L
015   13    0D    CR  '\r' (carriage ret)     115   77    4D    M
016   14    0E    SO  (shift out)             116   78    4E    N
017   15    0F    SI  (shift in)              117   79    4F    O
020   16    10    DLE (data link escape)      120   80    50    P
021   17    11    DC1 (device control 1)      121   81    51    Q
022   18    12    DC2 (device control 2)      122   82    52    R
023   19    13    DC3 (device control 3)      123   83    53    S
024   20    14    DC4 (device control 4)      124   84    54    T
025   21    15    NAK (negative ack.)         125   85    55    U
026   22    16    SYN (synchronous idle)      126   86    56    V
027   23    17    ETB (end of trans. blk)     127   87    57    W
030   24    18    CAN (cancel)                130   88    58    X
031   25    19    EM  (end of medium)         131   89    59    Y
032   26    1A    SUB (substitute)            132   90    5A    Z
033   27    1B    ESC (escape)                133   91    5B    [
034   28    1C    FS  (file separator)        134   92    5C    \  '\\'
035   29    1D    GS  (group separator)       135   93    5D    ]
036   30    1E    RS  (record separator)      136   94    5E    ^
037   31    1F    US  (unit separator)        137   95    5F    _
...
077   63    3F    ?                           177   127   7F    DEL

Copyright and license for the table.

^H corresponds to backspace character, ^M to carriage return, ^J to newline, ^I to tab, ^[ to escape, etc.

JoL
  • 4,735
2

The ^ character stands for the control key. ^[ produces ESCAPE, or ASCII 27. Capitalization in this context is normally not significant, and ^A means the same as ^a, namely the control key pressed at the same time as the "a" key.

^[^@ means ESCAPE followed by control-@ (depending on the keyboard layout, you may have to press Shift or Alt-Gr at the same time in order to produce "@").

^X^[q means control-x followed by ESCAPE followed by q.

^[[1;5C means ESCAPE followed by the character string "[1;5C". To me, this looks like a terminal control sequence, which changes text properties like colour, boldness, italics and so on.

I don't know if the usage of ^ to signify the control key is standardized, but it is described by a Wikipedia page. Producing ASCII 27 by typing ^[ was probably pioneered by DEC terminals like VT100 and might be a standard by now.

berndbausch
  • 3,557