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