在终端中检测 Shift + keyup/down

在终端中检测 Shift + keyup/down

我该怎么做呢?我想要一个终端菜单,其中shift+upshift+down选择多行。 ncurses似乎有问题。

我不一定需要高级终端库。我只想处理这个问题,除此之外我的 IO 应该非常简单。

有什么建议吗?

答案1

从问题的上下文来看,shift+upshift+down参考shift-cursor-upand shift-cursor-down(而不是例如shift-page-upand shift-page-down),因为问题询问的是如何选择多个线

这其实不止一个问题:

  • 首先,如何让ncurses识别shift+up等等,以及
  • ncurses 菜单库是否执行此操作,以及
  • 如果没有的话,如何获得一个菜单来做到这一点。

首先,ncurses 为一组可移植(更多/更少)的特殊键提供预定义(每个 X/Open Curses)定义。参考术语信息(5),您可能会注意到:

   key_sf                    kind   kF   scroll-forward key
   key_sleft                 kLFT   #4   shifted left-arrow
                                         key
   key_sr                    kri    kR   scroll-backward key
   key_sright                kRIT   %i   shifted right-arrow
                                         key

但没有任何标记为“上移箭头键”。只有事后诸葛亮才能将kindkrikLFT和联系起来kRIT。在 1999 年向 xterm 添加对修改后的特殊键的支持之前,几乎没有现有技术:

补丁 #94 - 1999/3/27 - XFree86 3.9Pf
向功能键添加参数以指示是否设置了 Shift、Control 或 Alt。这些代码基于 Jeffrey Altman 对带有 PC 键盘的 DEC VT510 的描述。

后来,该方案进行了修改,以减少应用程序的混乱。其他从 xterm 复制该功能的开发人员并没有效仿修改他们的程序:

补丁 #167 - 2002/8/24 - XFree86 4.2.0
添加modifyCursorKeys资源来控制如何使用 Shift 和类似修饰符来创建光标转义序列。默认情况下,修改后的转义序列始终以 CSI 开头,并将修饰符作为第二个参数,以避免将第一个参数解释为重复计数的应用程序混淆。可以通过将资源设置为 0 来获得原始行为(与 Stephen J Turnbull、Jeffrey Altman 的新闻组讨论)。

同时,在 ncurses 中,将这些合并到终端描述中似乎很有用(因为 ncurses 使用终端数据库,而不是 tmux 使用的表格)。这些依赖于由以下引入的用户定义功能的特性ncurses 5.0。在终端数据库中,xterm 中提到了该功能2004年:

# 2004-07-17
#       * add xterm-pc-fkeys -TD

其中(除了早在2001年)尝试处理可能与 xterm 资源的不同组合一起使用的修饰符编码的变化 - 以及与 xterm 编码方案不同程度不同的相似内容。

用于用户定义功能的约定首先将kDN和添加kUP到列表(您的shift+downshift+up),以及与 xterm 修饰符代码相对应的数字。很久以后,人们发现kindkri可能具有相同的含义。但结果,你可能会发现带有kDN和 的终端描述kUP(只有 ncurses 读取——其他直接读取终端数据库的应用程序和库忽略了这一点大约 16 年)。

扩展功能总结在终端数据库

现在(从第二部分开始),ncurses 确实提供了一个菜单库。这是(带有一些扩展,例如支持多字节字符)SVr4 菜单库的重新实现。请参阅手册页了解menu_driver(3x)为此,以及ncurses-示例展示了图书馆。简而言之,菜单库不会预定义您所询问的行为,但应用程序可以使用该库来执行所要求的操作。首先看看如何使用这个细节:

REQ_TOGGLE_ITEM
选择/取消选择一个项目。

更大的问题是在此应用程序中使用用户定义的功能所引发的。大多数使用表单库和菜单库的应用程序都依赖于使用特殊键的预定义符号进行 case 语句。因为shift+upshift+down你不会有这个(除非kind和的巧合kri被注意到并应用)。对于用户定义的功能,没有预定义的键代码(例如KEY_DOWNcurses.h)。相反,您有由运行时定义的值确定key_defined功能。因此,而不是一个简单的案例陈述(有KEY_SDOWN)中没有curses.h,需要一些间接。

答案2

终端传输字符,而不是密钥。大多数字符都是可打印的,这没有留下太多空间来编码功能键和键和弦。功能键被编码为转义序列,即以转义字符开头的字节序列(字节值 27,可以像\e许多编程语言一样写出)。有关更多详细信息,请参阅键盘输入和文本输出如何工作?

对于每个键或键和弦发送的转义序列没有通用标准。 curses 库提供了一个解码功能键的抽象层。它使用术语帽(旧式)或术语信息(现代)底层图书馆;如果您不想与curses链接,可以直接使用termcap/terminfo。

Up或者,您可以对和 的常用控制序列进行硬编码Down。虽然没有标准,但几乎每个终端都会发送\eOAor \e[AforUp和 another \eOBor \e[Bfor Down,而且我从未见过为不同的密钥发送这些序列的终端。

键和弦Shift是另一回事:它们发送的转义序列更加多样化,并且许多终端无法区分Up例如Shift+ Up。除非您只支持一组有限的配置,否则您不能依赖它们的不同。不断出现的标准但许多流行的终端模拟器仍然不支持它们。

终端不发送按键事件。 (不过,根据您的描述,您的用例不需要它们。)

除非您能够负担得起特定的终端模拟器(例如最近的 xterm),否则不要依赖用户能够键入Shift+ Up。支持替代方法,例如“开始多项选择”键后跟纯Up/ Down

答案3

showkey在命令提示符下尝试使用类似的工具。

按箭头键,然后按 Shift+箭头。

例如,如果您^[[A同时按下箭头键和 Shift+箭头键,我认为这表明您的终端仿真器忽略了 Shift 修饰键。我刚刚测试了三个流行的终端仿真器,其中 2 个忽略了 Shift 键。

这不是最好的答案,但可能会帮助某人更好地使用Jupp允许移位箭头选择的编辑器。

相关内容