Terminal – Characters Printed When Alt+Arrow Keys Are Pressed

command linekey mappingterminal

When I press AltUp, A printed to terminal screen. Same thing happened when I pressed AltDown but B is printed instead.

Other characters that I realized;

AltLeft = D and AltRight = C

What is the purpose of these commands?

Best Answer

Depending on how the terminal is configured, typing Alt+Key is like typing the Esc and Key keys in sequence, so it sends the ESC character (aka \e or ^[ or \033) followed by the character or sequence of characters sent upon pressing that Key.

Upon pressing Up, most terminal emulators send either the three characters \033[A or \033OA depending on whether they're in application keypad mode or not.

The first one does correspond to the escape sequence which when output to the terminal, move the cursor up. If you do:

printf '\nfoo\033[Abar\n\n'

You'll see bar written after foo one row up. If you do:

stty -echoctl; tput rmkx; read foo

You'll see that the arrow keys do move the cursor around.

When an application like zsh or vi reads that sequence of characters from the terminal, it interprets it as the "Up" action, because it knows from the terminfo database (kcuu1 capability) that it is the escape sequence sent upon pressing Up.

Now, for Alt-Up, some terminals like rxvt and its derivatives like eterm send \033 followed by the escape sequence for Up (that is \033\033[A or \033\033OA), while some others like xterm or gnome-terminal have separate escape sequences for those types of keys when used with the combination keys like Alt, Shift, Ctrl.

Those will typically send \033[1;3A upon Alt-Up.

When sent to the terminal, that sequence will also move the cursor up (the second parameter (3) is ignored). There's no corresponding keypad key, so it's the same sequence sent upon Alt-Up in or out of application keypad mode.

Now whether it's \033\033[A or \033[1;3A, many applications don't know what those sequences are for. The terminfo database won't help them, because there's no such capability that defines what characters those key combinations send.

They will try their best to interpret that sequence. bash for instance will interpret \033[1;3 as an escape sequence, doesn't know anything about it, so does nothing, followed by A. zsh, will stop reading as soon as it finds out there's no known matching character sequence. There's no escape sequence that it knows that starts with \033[1 so it will skip that, and read the rest: ;3A and insert that in the line editor.

Many applications like vi, zsh or readline based ones like gdb or bash (though beware bash uses a modified version of readline) allow you to add bindings for any sequence of characters.

For instance, in zsh, you may want to bind Alt-Up, Alt-Down like:

bindkey '\e[1;3A' history-beginning-search-backward
bindkey '\e[1;3B' history-beginning-search-forward

Those are to search the history backward and forward for command lines that start like the current one up to the current position of the cursor which is quite handy to recall previous commands.