我怎么知道用户在带有 ncurses (Linux) 的控制台中按下了 ESC 键?

How can I know that the user hit the ESC key in a console with ncurses (Linux)?

我在检测我是得到一个普通的 ESC 键(只是代码 27)还是另一个 special 时遇到问题向我发送三个字节的键,例如向上箭头:ESC [ A (27 91 65) .

现在,我理解了转义序列,但我不明白的是我怎么可能知道用户实际输入的是 ESC 而不是特殊键,因为两者都以 27 开头ESC 只是 27?

请注意,我使用 ncurses 中的 wgetch() 函数,如下所示:

// initialization not shown initscr() should be enough for this test
while(!f_should_exit)
{
    int c(wgetch(f_win_input));

    // show codes of what the user types
    //
    printf("got [%d] ", c);
    // prints 27 when I hit ESC
    // prints 27 91 65 when I hit Arrow Up
}

我在 vim 中一直使用 ESC 和箭头键,所以我想有一种简单的方法可以专门检测按下了哪个键?!

这是 X/Open Curses 的标准功能。 wgetch 的手册页在 keypad mode 中对此进行了讨论:

When a character that could be the beginning of a function key is received (which, on modern terminals, means an escape character), curses sets a timer. If the remainder of the sequence does not come in within the designated time, the character is passed through; otherwise, the function key value is returned. For this reason, many terminals experience a delay between the time a user presses the escape key and the escape is returned to the program.

默认情况下,对于给定的 window,keypad 未设置为真,即库不会这样做(如果您需要功能键,您的程序必须这样做):

keypad(win, TRUE);

ncurses 的输入选项手册页中描述了超时。要将转义字符与函数(或光标或键盘键)区分开来,您可以使用 notimeout,如 nodelay:

的讨论中所述

While interpreting an input escape sequence, wgetch(3x) sets a timer while waiting for the next character. If notimeout(win, TRUE) is called, then wgetch does not set a timer. The purpose of the timeout is to differentiate between sequences received from a function key and those typed by a user.