我正在尝试使用GNU Readline库绑定到C中的箭头键.我已经打印出所有可能的ASCII(0-255)键值组合rl_bind_key,但似乎没有检测到箭头键.
我怎么能绑定他们?
static int readline_func(int count, int key) {
printf("key pressed\n");
return 0;
}
int i = 0;
for (; i < 255; i++) {
rl_bind_key(i, readline_func);
}
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助!
绑定箭头键并不是那么简单.
首先,箭头键不是单个字符; 它们是字符序列.每个箭头键发送的精确字符序列将取决于您的终端仿真器,但如果您使用Linux与类似xterm的终端仿真器,您可能会发现箭头键发送序列:
(您可以在Thomas Dickey维护的控制序列的有用纲要中找到更多信息.请注意,这CSI是"控制序列启动器" ESC[).
要绑定这些序列,您需要使用rl_bind_keyseq,指定readline样式的"keyseq"(请参阅man readline;搜索keyseq).例如,要将右箭头绑定到函数,可以调用:
rl_bind_keyseq("\\e[C", right_arrow_function);
Run Code Online (Sandbox Code Playgroud)
初始readline绑定包括所有标准键的绑定,使用各种不同的可能的key-to-keyseq映射,以防终端仿真器使用其他一些仿真.
您可能认为使用rl_bind_key绑定转义键(0x1B)会覆盖该键序列(因为它以转义开头),但这不是readline的工作方式.
Readline使用一系列链接的键映射来绑定多字符序列,其中序列中的每个键依次绑定到下一个键映射.精确的机制并不重要 - readline将处理它 - 但你需要知道绑定绑定键序列的前缀是不可能的,因为前缀将绑定到子键映射和子键-keymap绑定优先于任何其他类型的绑定.
因此,任何重新绑定绑定keyseq的前缀的尝试都将失败,而不会出现任何错误指示 ; 即使绑定没有效果,rl_bind_key(或rl_bind_keyseq)也将返回0.因此,您对所有可能的8位字符的循环将尝试绑定ESC,并且调用rl_bind_key将成功,但转义键将保持绑定到子键映射.(我个人发现缺少错误会让人感到恼火;获得错误指示会很好.)
当rl_command_function被调用时,顺便说一下,该key参数将包含用于序列中的最后一个键的代码.(这是因为它是实际保存绑定信息的最后一个键,在相应的子键映射中.)这对于箭头键是可以的,但它对于绑定大量键是很烦人的,包括PageUp和PageDown ,其码序列具有形式ESC[p~其中p一些(可能是多位)数识别的关键,但在所有的序列的最后一个字符是~.