What are the characters printed when Alt+Arrow keys are pressed?

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.


You can use Crtl+v to return input codes of your keyboard. If you do that for arrow keys, you will get [[D^, [[C^, [[A^, and [[B values. There aren't any default bindings for Alt+arrow keys, so it seems that performed action is printing letter code alone. Hovewer, if you create your local version of readline library configuration file:

$ cp /etc/inputrc ~/.inputrc

And add a line:

"\e[1;3C": "sometexthere"

Where [1;3C is input code of Alt+ (you can get it same way as before using Crtl+v shortcut) and restart your terminal then Crtl+ shortcut will return you text "sometexthere" and other Alt+arrow shortcuts will stop returning characters.

Instead text you can pass a bindable command from http://www.gnu.org/software/bash/manual/html_node/Bindable-Readline-Commands.html#Bindable-Readline-Commands like

"\e[1;3C": unix-line-discard

to have same effect like Crtl+u (delete line).

More information here: http://cnswww.cns.cwru.edu/php/chet/readline/readline.html


The Alt key is often used as a meta modifier. Cursor- and function-keys are referred to as special keys since they may send multiple characters — and the characters which are sent can be altered.

Some users, e.g., for bash expect that pressing Alt will send a key prefixed by the escape character. The documented "meta" feature (see terminfo(5)) deals with the eighth bit:

If the terminal has a "meta key" which acts as a shift key, setting the 8th bit of any character transmitted, this fact can be indicated with km. Otherwise, software will assume that the 8th bit is parity and it will usually be cleared. If strings exist to turn this "meta mode" on and off, they can be given as smm and rmm.

bash knows about that, too (see ncurses FAQ), but few of its users are interested in the feature. Nonetheless, they're accustomed to referring to Alt as "meta", even though meta mode is turned off. Both rxvt and xterm have had this feature since (at least) the early 1990s.

Other users (since xterm introduced the feature in patch #94, 1999) may expect the modifier information to be encoded as a parameter in the sequence of characters that a special key would send. XTerm's documentation referred to these modified keys as "PC-style" function keys to distinguish them from "VT220-style" (which did not have modifiers). An unmodified cursor key might send ESC[A, but it is also legal to have a parameter, e.g., ESC[5A, which an application should understand as repeating that five times. The first version of xterm's PC-style keys used that "5" to denote control, and a later version changed it to avoid confusion with the repeat count. So...

ESC[5A

suggests that the application move the cursor up 5 rows, while

ESC[1;5A

suggests that it move up one row, telling the application that a control key was pressed.

The useful combinations have been in the ncurses terminfo database since 2004:

# 2004-07-17
#       * add xterm-pc-fkeys -TD

The terminfo database shows the current version of xterm+pcfkeys with a comment showing how the modifiers are encoded:

# This fragment describes as much of XFree86 xterm's "pc-style" function
# keys as will fit into terminfo's 60 function keys.
# From ctlseqs.ms:
#    Code     Modifiers
#  ---------------------------------
#     2       Shift
#     3       Alt
#     4       Shift + Alt
#     5       Control
#     6       Shift + Control
#     7       Alt + Control
#     8       Shift + Alt + Control
#  ---------------------------------
# The meta key may also be used as a modifier in this scheme, adding another
# bit to the parameter.

(Alt and meta are not necessarily the same key). That is a building block (in turn composed of other building blocks) from which the xterm terminal description is formed. It uses an extension provided in ncurses since 1999 which allows user-defined names. Since termcap supports only 2-character names, and 1023-byte descriptions, there was no reason to make these extended names available through the termcap interface. They're readily available to applications using the terminfo interface.

Now comes a difficulty: there are a few ways for an application to determine what a key sequence like that represents:

  1. analyze the sequence of characters completely
  2. partly analyze it and throw away the control modifier if not needed
  3. just compare the sequence of characters against a dictionary, hoping to determine the meaning that way.

Few programs would do the first; some text editors would do the second (actually, I did this for ded in the late 1980s). Developers for applications such as bash chose the third route by assuming that most of the information is in termcap. Alternatively, they could have chosen to make a table with termcap/terminfo information and use the interface which gave the best information. xterm does this for the tcap-query feature, providing vim with the actual function key assignments.

Since none of the strings that bash compares against match the strings it receives, it can get confused, settling for partial matches (such as the escape character by itself).

Further reading:

  • How to fix the shifted function keys in vim in xterm in gnome-terminal?