在终端中检测 shift + keyup/down

PSk*_*cik 9 terminal ncurses tty

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

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

有什么建议吗?

Tho*_*key 7

从问题的背景下,shift+upshift+downshift-cursor-upshift-cursor-down(而不是,例如,shift-page-upshift-page-down),因为这个问题问到选择多

这实际上不止一个问题:

  • 首先,如何让 ncurses 识别shift+up,等等,以及
  • ncurses 菜单库是否执行此操作,以及
  • 如果没有,如何获得菜单。

首先,ncurses 为一组可移植(更多/更少)的特殊键提供了预定义的(每个 X/Open Curses)定义。参考terminfo(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
Run Code Online (Sandbox Code Playgroud)

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

补丁 #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引入的用户定义功能的特性。在终端数据库中,2004 年提到了 xterm 的功能:

# 2004-07-17
#       * add xterm-pc-fkeys -TD
Run Code Online (Sandbox Code Playgroud)

它(除了巩固早在2001 年的早期工作之外)试图处理可能与 xterm 资源的不同组合一起使用的修饰符编码的变化——以及与 xterm 编码方案在不同程度上不同的相似之处。

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

扩展功能汇总在终端数据库中

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

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

更大的问题是在此应用程序中使用用户定义的功能引起的。大多数使用表单库和菜单库的应用程序依赖于使用特殊键的预定义符号进行 case-statement。对于shift+upshift+down你不会有(除非的巧合kind,并kri指出和应用)。对于用户定义的功能,没有预定义的键码(例如KEY_DOWNin curses.h)。相反,您拥有由key_defined函数确定的运行时定义的值。因此,而不是一个简单的case语句(那里没有KEY_SDOWNcurses.h),需要一些间接。


Gil*_*il' 6

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

\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n