8

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
kend=\EOF,

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)

EDIT

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
    home=\E[H,
    khome=\EOH,
  • 1
    The difference between home and khome is that the khome string is the sequence pressing the Home key produces, whereas home string is the sequence that should be sent to the terminal to move the cursor to the home position. To my knowledge, terminfo does not define an end capability, just kend. – Johan Myréen Aug 1 '17 at 7:36
  • @JohanMyréen Could you please explain what is "home position" of a cursor with an example? And why kend is defined as \EOF in terminfo, whereas the terminal generates \E[F? Is this a bug in Debian's terminfo? And how ncurses manages to detect it as KEY_END nevertheless? – Igor Liferenko Aug 1 '17 at 8:00
  • The home position is the upper left corner of the screen. – Johan Myréen Aug 1 '17 at 8:08
9

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:

  • Yes, I'm using keypad function. But with the question "how ncurses manages to detect it as KEY_END" I meant "how keypad decodes ^[[F into kend" (considering that keypad uses terminfo database to interpret the keychords). If I understood correctly, this happens because showkey -a is in cursor mode, whereas ncurses application is in application mode. – Igor Liferenko Aug 1 '17 at 8:42
  • showkey doesn't switch between normal/application modes. It's a Linux-specific program, making assumptions about the Linux console, rather than using the terminal database – Thomas Dickey Aug 1 '17 at 8:46
  • If showkey doesn't switch between modes, then it uses some default state, whatever it may be called. The point is that showkey prints ^[[F, not ^[OF, which lead to my confusion. (I just used showkey to visually represent the actual keychord which is being sent by the terminal by pressing on a keyboard button, without suspecting that there may be some subtleties involved.) – Igor Liferenko Aug 1 '17 at 8:59
  • Yes, that's "normal" mode (the usual way of referring to this). You could of course initialize your terminal using tput smkx and get different results. – Thomas Dickey Aug 1 '17 at 9:05
  • I think that there is a bug in less utility: it puts itself into application mode, but then fails to interpret keypad enter key. Should I submit a bug report? (You may check this by starting less and pressing keypad enter key after typing / - it will output ESCOM, instead of doing what enter key must do.) – Igor Liferenko Aug 1 '17 at 9:14
5

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."

  • What is the procedure of switching to "application mode"? Is it done by ncurses? – Igor Liferenko Aug 1 '17 at 8:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.