Search code examples
cunixttytermcap

Termcap tgetstr getting arrow keys


I'm trying to get the string representing the arrow key up from the termcap database. Using the following:

char *buffer = malloc(2048);
tgetent(buffer, getenv("TERM")); //TERM = xterm-256color
char *key_up = tgetstr("ku", &buffer); // gives me \EOA

ku String of input sent by typing the up-arrow key.

The problem is the arrow key up is actually passed as \E[A when typing into the program. It's also passed like this to cat. I tried with different terminal emulators and shells and they all passed it the same way.

So I decided to hardcode this value for the key instead of using the ku value, and it works, but doesn't feel right.

Am I missing something here? How can I programmatically get the right ku value?


Solution

  • Terminal descriptions are written for full-screen applications, which are initialized using one or more terminal capabilities assigned to this. About half of the terminal descriptions initialize the terminal's cursor- and keypad-keys to use application mode. In application mode, those keys send different characters.

    The ncurses FAQ My cursor keys do not work goes into more detail.

    If you are trying to use a terminal description for some non-screen command-line application, you could make your command-parser treat both \E[ (CSI) and \EO (SS3) as the same thing, and ignore the difference between the two modes. That was done in some configuration for zsh, as mentioned in the xterm manual page.

    By the way, if your "termcap" is actually an interface to a terminfo system (such as ncurses), it is not necessary to allocate the buffer, since that is ignored. ncurses' manual says:

    • The emulation ignores the buffer pointer bp. The termcap library would store a copy of the terminal description in the area referenced by this pointer. However, ncurses stores its terminal descriptions in compiled binary form, which is not the same thing.