4

I just noticed this by accident.

I use the vi readline mode (run set -o vi in bash) so it is particularly noticeable; in emacs readline mode I don't think Esc does anything, but in vi mode it exits insert mode (enters normal mode).

I don't see Shift-Tab documented in man bash, and it would seem that its interpretation as an Esc key is at a more basic level than bash. Possibly in readline?

It works on Mac OS X as well as Linux.

Where can I find this documented?

  • 1
    There are many manuals to review in the 5 part journey of a keypress between keyboard and CPU. 1: The OS hears a keycode from the keyboard and relays that to itself for first processing to affect the windowing system. 2. Your OS transmits some but not all to the focused application, a terminal app. 3. The terminal app hears the keycode, some affect it, some are passed through to bash. 4. bash hears the keycode and uses .inputrc to trap some and pass through still others to gnureadline. 5. gnu readline under the hood traps those keys and relays codes to low level C executable .so files. – Eric Leschinski Jan 12 at 4:23
6

Shift+Tab on several terminals sends an escape sequence like this

ESC [ Z

It has been part of the Linux console terminal since 1995, part of xterm since 2002, and used in terminals emulating one or the other of those since then.

In the terminfo description, this would be expressed as

kcbt=\E[Z,

and kcbt is documented in terminfo(5):

key_btab                  kcbt   kB   back-tab key

From the standpoint of parsing, there is no difference between this and pressing some function-key. readline does have special cases for several editing keys (seen after the call to tgetent in bash's lib/readline/terminal.c), but the termcap "kB" is not part of that.

  • This escape sequence comes from the ANSI escape codes that were popularized by DEC VT terminals. – chicks Oct 25 '15 at 2:08
  • From your terminfo database, it would seem ESC [ Z as kcbt predate Linux by a long shot. – Stéphane Chazelas Nov 12 '15 at 21:08
  • Maybe/maybe not: MSDN does not show this - it shows a different sequence. The earliest reliable source I can see at the moment for this escape sequence is no earlier than around 1995. A book discussing MS-DOS 6.22 matches MSDN's description for instance. – Thomas Dickey Nov 12 '15 at 22:34
3

it would seem that its interpretation as an Esc key is at a more basic level than bash. Possibly in readline?

It's even lower than that. This is a fundamental property of how terminals work on Unices and Unix-alike operating systems. The operating system sees terminal I/O as a sequence of 8-bit (or even 7-bit) characters. Function keys and extended keys are transmitted as multiple-character escape sequences.

In real terminals, these escape sequences are generated by firmware in the terminal itself. In terminal emulator programs, the terminal emulator turns keystroke data (that it has received through whatever user interface it uses to talk to a keyboard, be that the X Window system, a USB hid device, or a Linux event device) into escape sequences.

Applications such as vim and various line editing libraries try to distinguish them from simple presses of the Esc key by (in effect) timing how long it is between reading the escape character and reading the following characters. If the characters arrive quickly enough one after the other, they are treated as an escape sequence.

Where can I find this documented?

The timeout treatment of escape sequences in input is documented in vim under :help ttimeout and for the Z Shell's ZLE in the zshzle manual page. The basic idea that terminals generate escape sequences is widely documented.

Documentation for the specific escape sequences that are generated is harder to come by. Many, nowadays possibly most, terminals (in particular emulated terminals) speak the escape sequences that have been spoken by DEC VT terminals (when they are in what Digital called "ANSI mode") for many years. DEC provides documentation for its terminals, and you can find it explicitly discussing what Shift+Tab is encoded as in chapter 8 of the VT525 Programmer Information doco.

However: If you are using a kernel virtual terminal on Linux or a BSD, where the terminal emulator program is part of the operating system kernel, the adherence to DEC VT conventions is markedly spotty when it comes to input control sequences. In part this is because operating systems such as FreeBSD actually adhere to the SCO XENIX virtual terminal conventions by default, here. The result is a strange admixture of DEC VT and SCO XENIX that has no correspondence with any real terminal.

The admixture is not just a mismatch between input and output terminal emulations. It is further compounded by the fact that modern configurations attempt to override the SCO XENIX defaults for input control sequences but do so only partially. So, for example: on recent FreeBSDs one can find that F6 is the DEC VT control sequence CSI 1 7 ~, rather than the SCO XENIX sequence that is compiled into the kernel terminal emulator, but Shift+F6 is still the compiled-in SCO XENIX control sequence CSI d rather than the DEC VT control sequence CSI 1 7 ; 2 ~.

And none of this is in the FreeBSD doco at all.

Further reading

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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