如何在ncurses下可靠地处理KEY_HOME和KEY_END
How to process KEY_HOME and KEY_END reliably under ncurses
我正在努力让 ncurses 生成 KEY_HOME 或 KEY_END 事件,而不是原始转义序列作为字符序列出现。
下面这个简单的 C 程序说明了这个问题:
#define _XOPEN_SOURCE 700
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
void clean(void)
{
echo();
nl();
nocbreak();
endwin();
}
int main(int argc, char *argv[])
{
setvbuf(stderr, NULL, _IONBF, 0);
initscr();
cbreak();
nonl();
noecho();
atexit(clean);
keypad(stdscr, TRUE);
clear();
refresh();
int ch = getch();
if (ch == ERR)
errx(EXIT_FAILURE, "getch");
warnx("read: %x", ch);
halfdelay(1);
while((ch = getch()) != ERR)
{
warnx("read: %x", ch);
}
exit(EXIT_SUCCESS);
}
使用-lncurses 编译,并将stderr 重定向到日志文件。
按 HOME 时:
test: read: 1b
test: read: 5b
test: read: 31
test: read: 7e
当按下UP时
test: read: 103
为什么 HOME 和 END(实际上还有 F1 等)没有被 ncurses 解析为 KEY_HOME?
您可能已将 TERM
设置为与终端行为不匹配的值。例如,linux
终端描述有 khome=\E[1~
(which corresponds to the example output), while xterm
has khome=\E[OH
。你可以使用
看到这个
infocmp linux xterm | grep khome
如果终端描述与实际行为不匹配,ncurses 将不会匹配传入的字节,并会像所示那样运行。
我正在努力让 ncurses 生成 KEY_HOME 或 KEY_END 事件,而不是原始转义序列作为字符序列出现。
下面这个简单的 C 程序说明了这个问题:
#define _XOPEN_SOURCE 700
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
void clean(void)
{
echo();
nl();
nocbreak();
endwin();
}
int main(int argc, char *argv[])
{
setvbuf(stderr, NULL, _IONBF, 0);
initscr();
cbreak();
nonl();
noecho();
atexit(clean);
keypad(stdscr, TRUE);
clear();
refresh();
int ch = getch();
if (ch == ERR)
errx(EXIT_FAILURE, "getch");
warnx("read: %x", ch);
halfdelay(1);
while((ch = getch()) != ERR)
{
warnx("read: %x", ch);
}
exit(EXIT_SUCCESS);
}
使用-lncurses 编译,并将stderr 重定向到日志文件。 按 HOME 时:
test: read: 1b
test: read: 5b
test: read: 31
test: read: 7e
当按下UP时
test: read: 103
为什么 HOME 和 END(实际上还有 F1 等)没有被 ncurses 解析为 KEY_HOME?
您可能已将 TERM
设置为与终端行为不匹配的值。例如,linux
终端描述有 khome=\E[1~
(which corresponds to the example output), while xterm
has khome=\E[OH
。你可以使用
infocmp linux xterm | grep khome
如果终端描述与实际行为不匹配,ncurses 将不会匹配传入的字节,并会像所示那样运行。