Why END key does not have terminfo entry?

On a Debian system pressing END key generates ^[[F:

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[F     27 0033 0x1b
         91 0133 0x5b
         70 0106 0x46

But why this keychord is not in terminfo?

$ infocmp -1 | grep end

Nevertheless, ncurses manages to correctly recognize it as KEY_END. How?

TERM is xterm-256color

BTW, what is the motivation behind having kend and end instead of just end ? (the same for khome and home)


As said in the comment of Johan Myréen, khome string is the sequence pressing the Home key produces. But on Debian pressing Home key produces home. Why?

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[H     27 0033 0x1b
         91 0133 0x5b
         72 0110 0x48
$ infocmp -1 | grep home
Asked By: Igor Liferenko


The problem with the Home key is that physical terminals and later the terminal emulators that emulate them have two modes: normal and Application Mode, and the escape sequences are different depending on the mode the terminal is in. Terminfo does not cope well with this. In normal mode (aka “Cursor Mode”) the End key escape sequence is ESC [ F, in Application mode ESC O F. Googling for this problem reveals the whole mess.

Edit From the terminfo source:

“The VT100 series terminals have cursor (“arrows”) keys which can operate
in two different modes: Cursor Mode and Application Mode. Cursor Mode
is the reset state, and is assumed to be the normal state. Application
Mode is the “set” state. In Cursor Mode, the cursor keys transmit
“Esc [ {code}” sequences, conforming to ANSI standards. In Application
Mode, the cursor keys transmit “Esc O ” sequences. Application Mode
was provided primarily as an aid to the porting of VT52 applications. It is
assumed that the cursor keys are normally in Cursor Mode, and expected that
applications such as vi will always transmit the string. Therefore,
the definitions for the cursor keys are made to match what the terminal
transmits after the string is transmitted. If the string
is a null string or is not defined, then cursor keys are assumed to be in
“Cursor Mode”, and the cursor keys definitions should match that assumption,
else the application may fail. It is also expected that applications will
always transmit the string to the terminal before they exit.”

Answered By: Johan Myréen

Johan Myréen’s answer was close, but not exactly the problem: most of the terminal emulators which you will use have normal and application modes for special keys. Terminal descriptions are written for one mode, which corresponds to what a full-screen application uses. Other applications (such as an interactive shell) typically do not initialize the screen to use application mode. Bash is an example of that.

In normal mode, xterm and similar terminals send escape[ (CSI) while in application mode, their keypads send escapeO (SS3). In terminfo syntax, that escape is E. So infocmp is showing you that the description uses application mode. The home capability is sent to the terminal, telling it how to move the cursor to the home position (upper left), and is not the same as khome (sent from the terminal using the keyboard).

Full-screen applications (such as those using ncurses) may send the terminal-capability strings for initializing the keypad. Some terminal descriptions do put the terminal into application mode, some don’t.

The use of kend versus end is a naming convention: in terminfo by convention any name beginning with k refers to a special key (function key, cursor key, keypad-key) to make it clear that these are strings to be read by an application. For example, kcub1 (cursor-backward key) is distinct from cub1 (move the cursor back one column).

ncurses recognizes the key as KEY_END because the application you are using will call the keypad function to initialize the terminal using the smkx (the mnemonic means “start keyboard-transmit mode”). That may/may not actually turn on application mode. Linux console’s terminal description does not, xterm’s does.

In principle, you could use tput for switching the mode (and get different results from showkey):

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[H     27 0033 0x1b
         91 0133 0x5b
         72 0110 0x48
^C        3 0003 0x03
^D        4 0004 0x04
$ tput smkx
$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[OH     27 0033 0x1b
         79 0117 0x4f
         72 0110 0x48

As a complication, curses will recognize only one name for a string. Some terminals (such as xterm) emulate older hardware terminals using different names for the keys on the editing keypad. In the xterm FAQ listed below, there’s the possibility of naming that “Home” key “Insert”…

Further reading:

Answered By: Thomas Dickey
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.