使用 bash shell 时,我尝试使用Shift+LEFT突出显示并复制我输入的命令(而不是使用鼠标)。但是,我得到了很多 C。后来我意识到Shift+UP使A
、Shift+DOWN使B
和Shift+RIGHT也使D
.
为什么会发生这种情况?
我认为它来自原始击键数据(^[[A
、^[[B
、^[[C
和^[[D
),但它只是一个大写字母(^[[
开头没有)。
Jde*_*eBP 11
这是一个可以追溯到 1980 年代的键盘输入协议,您的外壳,而不是像 M. Vazquez-Abrams 的回答中那样的“终端驱动程序”(无论应该是什么)没有正确处理它。此外,它是一个完全有效的控制序列。
终端发出功能键和扩展按键的控制序列。它们可以发出 DECFNK 控制序列,它们是 CSI 引入的控制序列;Linux功能键控制序列,是一种不同的CSI引入序列;SCO控制台功能键控制序列,是CSI引入的第三种序列;移动的单个字符,以 SS3 为前缀;或者,在这种情况下,各种事物的 ECMA-48 标准序列。
(SS3 和 CSI 是控制字符,在 C1 范围内。Single Shift 3 和 Control Sequence Introducer。)
您的(IBM Model M 类似或类似的)键盘上有两个特定的小键盘,一个计算器小键盘和一个光标小键盘。DEC VT 式终端仿真器(这是您可能遇到的大多数终端仿真器,从内核中的到 unicode-rxvt)采用的模型是两个键盘都具有可单独切换的应用程序/正常模式。一个全屏 TUI 应用程序,使用 libedit 或 GNU readline 库(或 ZLE)的东西,比如你的 shell,以及一些其他类型的应用程序指定他们想要的模式,然后通过读取突发来监听来自终端的控制序列字符数(因为人类无法像终端或终端模拟器发送控制序列一样快的速度在任何地方输入完整的 ECMA-48 控制序列,Esc 来自终端仿真器的键发送以 ␛ 字符开头的控制序列)。
因此,可以选择应用模式,即无法知道按下了哪些修饰符,但可以区分两个向左箭头键;以及普通模式,即无法区分两个箭头键,但可以知道按下了哪些修饰符。
更详细地说:ECMA-48 控制序列的 DEC 增强是控制序列有两个参数:
这就是 DEC VT 终端自 1980 年代以来一直在做的事情。近年来,几个终端模拟器终于引入了相同的功能(尽管如前所述,XTerm 弄错了)。
问题在于您的 GNU readline 库、libedit、ZLE 等并没有真正正确地处理协议。他们不完全是罪魁祸首。它们依赖于 termcap 和 terminfo 系统,这在这里根本无法胜任。termcap 和 terminfo 并没有真正具有可以变化的输入控制序列的概念,更不用说多模式键盘了。
为此,您必须查看 Vim 之类的东西,它可以使用特殊的 terminfo 覆盖进行编程,以指定遵循上述协议(参见:help xterm-modifier-keys
Vim 中的控制序列)或 NeoVIM,它使用Paul Evans 的 libtermkey及其CSI 驱动程序。libtermkey 的 CSI 驱动程序是人们如何正确处理来自类似 DEC VT 的终端仿真器的键盘输入的方法。它是一个实际的 ECMA-48 状态机解析器,可以正确解码控制序列。
但是你的 shell 正在做的是在 terminfo 中查找箭头键的条目,并且只匹配那些特定的控制序列。
具体来说:
kcub1
其 terminfo 记录中查找您的终端的功能。这是记录中的一个teken
,例如:% tput -T teken kcub1|hexdump -C 00000000 1b 5b 44 |.[D| 00000003 %
1
;
2
D
。相反,它使用 7 位替代方案并发送␛
[
1
;
2
D
,其中␛
[
以 7 位字符编码 CSI 的方式是什么。失败模式是什么取决于它尝试模式匹配的确切输入序列集,因为这决定了它在确定它具有没有可能匹配的序列之前吞下多少字符。这当然又取决于您的终端的 terminfo/termcap 记录实际包含的内容以及您告诉 shell 终端是什么终端类型。
对这类事情的本地修复是在 shell 中使用键绑定来发挥创意。这就是为什么,例如,你会发现人们在他们的.zshrc
s 中使用 Z shell 做这种事情:
bindkey "\e[1;5D" 反向词 bindkey "\e[1;5C" 前向字
不幸的是,没有非本地修复。这将涉及相当显着地重新构建您的 shell 的输入处理。这种重新架构早就应该进行了。(见证 NeoVIM。)但还没有人解决它。
DECFNK
. “ANSI 控制功能”。 VT510 终端程序员信息。EK-VT510-RM。1993 年 11 月。数字。按Ctrl+V将导致下一个按键按字面输入。对于Shift+ \xe2\x86\x91,结果为“^[[1;2A”。终端驱动程序将“^[[1;2”用作无效转义序列,只留下“A”。
\n 归档时间: |
|
查看次数: |
6467 次 |
最近记录: |