Bash – How to Find Keybinding Represented by a Character Sequence

bashkeyboard shortcutszsh

To get the character sequences of a particular keyboard shortcut we use showkey -a or verbatim insert (Ctrl+V).

What is the opposite of it? How can I get the keyboard shortcut in human readable format from character sequences?

I used some keybindings for example

^[^?
^X^U
^[[3;5~
^[[1;2D
^[[1;2C
^[[1;5C
^[[1;5D
^[[1;6C
^[[1;6D
....

Now I do not remember which key/key-combination they used to represent.

How can I find that out?

Update 1

I am looking for something which will output Ctrl+R or Ctrl+Delete etc, I mean in human readable format.

Any reference to a table which has possible character sequences and their human readable formats will also do.

Best Answer

As long as your terminal generates input control sequences in ECMA-48 form, or the DECFNK, Interix, SCO Console, or Unicode RXVT forms, you can feed it to my console-decode-ecma48 tool, with the --input command-line option to tell it that the character stream is input rather than output. This is true for most terminals and terminal emulators that you will encounter in practice nowadays.

Here is what it does with your input, with ^[ replaced by the actual character of course:

% console-decode-ecma48 --input << EOF
^[^?
^X^U
^[[3;5~
^[[1;2D
^[[1;2C
^[[1;5C
^[[1;5D
^[[1;6C
^[[1;6D
EOF
DEL
LF
U+00000015
LF
DEC Control+DELETE
LF
Level2+CUB 1
LF
Level2+CUF 1
LF
Control+CUF 1
LF
Control+CUB 1
LF
Control+Level2+CUF 1
LF
Control+Level2+CUB 1
LF
%

As noted at https://unix.stackexchange.com/a/504056/5132 , if you want to decode what some terminals do with ⎇ Alt key chords you will also need the --no-7bit option; otherwise you'll get the ECMA-48 standard decoding of the 7-bit aliases for the C1 control characters.

CUF and CUB are the standard ECMA-48 names, of course: "CUrsor Forward" and "CUrsor Backward". See the manual.

The rules for terminal control sequences may surprise you. You typed , DEL, , , and . The rules for terminal control sequences handle this as follows:

  1. The begins an escape sequence.
  2. The DEL is handled immediately as a control character, leaving the escape sequence still pending.
  3. The is handled immediately as a control character, leaving the escape sequence still pending.
  4. The cancels (it being in the name) the pending escape sequence.
  5. The is processed as a C0 control character. console-decode-ecma48 prints its Unicode code point in the case of this particular character.

Note that no shell that I know of actually contains a correct ECMA-48 decoder. Shells do pattern matching, which is significantly imperfect at handling the actual ECMA-48 encoded stuff that terminals have been sending all along. This leads to things like the problems discussed at https://unix.stackexchange.com/a/499139/5132 and https://unix.stackexchange.com/a/520429/5132 amongst many others.

console-decode-ecma48 actually has a proper ECMA-48 decoder with a control sequence state machine, with variances for the SCO Console, Interix, and so forth. It won't show you exactly what things like GNU Readline, libedit, and ZLE will make of your input, because they don't get the protocol right.

But it will show you what an ECMA-48 terminal thought that it was sending, which is what you want here.

Further reading