ncurses捕获扩展键(Control-left,Shift-Function等)

时间:2011-09-23 11:12:27

标签: ncurses

我试图在我的ruby程序中捕获Control-Left,Shift-F10等。通常情况下,只使用getch我得到一个包含27,91,50,50,126的整数列表。但是我担心这些可能是系统或终端依赖的。在谷歌上搜索后,我发现了use_extended_names,tigetstr等。我找到了一个使用这些程序的C程序,它在运行时发现密钥代码(由Thomas Dickey提供)。我运行它似乎发现了扩展键,但是然后同一程序中的getch仍然给了我通常的整数列表,例如C-left的[27,91,53,68],无论如何。我期望获得一个回报值,即它所提到的值。

我缺少什么?

按下Control-left时的输出:

keypress=27
keypress=91
keypress=53
keypress=68
key=kLFT5, code=540
key=kEND5, code=525
key=kHOM5, code=530
key=kHOM3, code=528
key=kUP5, code=561
key=kDN5, code=520

我不应该只得到540吗?

这是keytest.c:https://gist.github.com/1237091

奇怪的是,在TERM = screen下运行时,所有代码都显示为0。以上是TERM = xterm。 (我在使用终端的OSX上)

2 个答案:

答案 0 :(得分:2)

Curses是在人们真正在终端中进行修改之前设计的。它的键处理模型实际上是一个扁平的值枚举,并且不容易处理任意键+修饰符组合。

为了更好地解决这个问题,我写了libtermkey,你可能会更幸运地使用它。

http://www.leonerd.org.uk/code/libtermkey/

它是一个C库,但它同时具有Perl和Python绑定。我想有人应该能够很容易地为它构建一些Ruby绑定。

答案 1 :(得分:0)

ncurses本身并不知道control-,shift-,meta-和alt-modifiers,因为它只知道字符。修饰符是特定终端所知道的。某些终端可以将键盘修饰符编码为它们发送给主机的字符。例如,xterm可以做到这一点。

terminfo(和termcap)具有预定义的特殊键列表(例如光标键,功能键),包括少量修改的特殊键(例如右移箭头)。预定义键在​​终端描述中具有明确定义的名称以及KEY_标题中的curses.h xxx 名称。 ncurses提供了两种扩展这些特殊键列表的方法

  • tic-x选项以及相应的use_extended_names函数(定义给定输入字符串的名称)。
  • define_key函数(指定getch为给定输入字符串返回的代码)。

ncurses终端数据库为修改后的特殊键提供了最有用的定义,重点是光标键和编辑键盘。 这有几个问题:

  • 终端数据库不提供所有定义,因为可移植的terminfo定义限制为4096字节。如果没有大小限制,那么可以想象,可以为xterm的键盘相关资源设置的每个(字面上)成千上万的组合生成完整的表格。
  • TERM设置为xterm的某些终端不会发送与xterm相同的字符串。 (事实上​​,大多数不同,虽然有些是子集而不是简单的不同)。
  • 对于给出的示例,terminfo中的字符串将是\E[5D,它似乎不是xterm的一个。 (OP表示这是OSX终端,从几年前开始 - 每个版本的OSX都包含对终端的更改,但OSX终端的版本尚未完全匹配xterm)。它似乎不是xterm的原因是修饰符(5)出现在第一个位置而不是第二个位置。 xterm在2002年(patch #167)弃用了它。
  • 在没有具体细节的问题中提到了功能键。 ncurses中使用的约定是为(几乎标准的)12个PC键盘功能键分配4个最有用的移位和控制修改器组合,以获得48个功能键。 terminfo中有60个预定义的功能键;如果还有其他众所周知的字符串,剩余的十几个字符串将被填写到最大限度。

使用terminfo制作预定义表格(以及大小和终端的问题假装有所不同)。 define_key函数对大小没有限制,并且长期以来一直可用于有特殊需求的应用程序。例如,可以通过合并最常见终端的最常见变体来使用它来构建表。