Why END key does not have terminfo entry?
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:
- How do I fix unix so that I can use the arrow keys in a terminal?
- My home/end keys do not work (ncurses FAQ)
- Why doesn't my keypad work? (xterm FAQ)
- Keypad and Function Keys (terminfo manual)
- User-Defined Capabilities (terminfo manual, commenting on other use of "k")
- Keypad mode (
getch
manual page)
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."