绑定到Readline库中的箭头键

Jam*_*lor 3 c readline

我正在尝试使用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)

谢谢你的帮助!

ric*_*ici 5

绑定箭头键并不是那么简单.

首先,箭头键​​不是单个字符; 它们是字符序列.每个箭头键发送的精确字符序列将取决于您的终端仿真器,但如果您使用Linux与类似xterm的终端仿真器,您可能会发现箭头键发送序列:

  • ↑  ESC[A
  • ↓  ESC[B
  • ESC[C
  • ESC[D

(您可以在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一些(可能是多位)数识别的关键,但在所有的序列的最后一个字符是~.