在 Debian 系统上按下END
键会生成^[[F
:
$ showkey -a
Press any keys - Ctrl-D will terminate this program
^[[F 27 0033 0x1b
91 0133 0x5b
70 0106 0x46
但为什么这个键和弦不在术语信息?
$ infocmp -1 | grep end
kend=\EOF,
尽管如此,恩诅咒设法将其正确识别为KEY_END
.如何?
TERM
是xterm-256color
kend
顺便说一句,拥有和end
而不是仅仅背后的动机是什么end
? (与khome
和相同home
)
编辑
正如 Johan Myréen 的评论中所说,khome
字符串是按 Home 键产生的序列。但在 Debian 上按 Home 键会产生home
.为什么?
$ showkey -a
Press any keys - Ctrl-D will terminate this program
^[[H 27 0033 0x1b
91 0133 0x5b
72 0110 0x48
$ infocmp -1 | grep home
home=\E[H,
khome=\EOH,
答案1
Johan Myréen 的答案很接近,但不完全是问题:您将使用的大多数终端模拟器都有普通的和应用特殊键的模式。终端描述是为一模式,对应于全屏应用程序使用的模式。其他应用程序(例如交互式壳)通常不初始化要使用的屏幕应用模式。 Bash 就是一个例子。
在普通的模式下,xterm 和类似终端发送escape[
(CSI)应用模式,他们的键盘发送escapeO
(SS3)。在 terminfo 语法中,逃脱是\E
。所以infocmp
向您展示描述使用应用程序模式。这home
能力已发送到终端,告诉它如何将光标移动到家位置(左上角),并且与khome
(发送从使用键盘的终端)。
全屏应用程序(例如使用 ncurses 的应用程序)可能发送用于初始化键盘的终端功能字符串。有些终端描述确实将终端置于应用程序模式,有些则不然。
指某东西的用途kend
相对end
是一个命名约定:在 terminfo 中,按照惯例,任何以以下开头的名称k指的是特殊键(功能键、光标键、小键盘键),以明确这些是应用程序要读取的字符串。例如,kcub1
(光标向后钥匙) 不同于cub1
(将光标向后移动一列)。
ncurses 将密钥识别为KEY_END
因为您正在使用的应用程序会调用keypad
smkx
函数使用(助记符的意思是“启动键盘传输模式”)来初始化终端。这可能/可能不会真正打开应用程序模式。 Linux 控制台的终端描述没有,xterm 的有。
原则上,你可以使用tput
用于切换模式(并从中得到不同的结果showkey
):
$ showkey -a
Press any keys - Ctrl-D will terminate this program
^[[H 27 0033 0x1b
91 0133 0x5b
72 0110 0x48
^C 3 0003 0x03
^D 4 0004 0x04
$ tput smkx
$ showkey -a
Press any keys - Ctrl-D will terminate this program
^[OH 27 0033 0x1b
79 0117 0x4f
72 0110 0x48
麻烦的是,curses 只能识别字符串的一个名称。某些终端(例如 xterm)使用不同名称的编辑键盘上的按键来模拟较旧的硬件终端。在下面列出的 xterm 常见问题解答中,可以将“Home”键命名为“Insert”...
进一步阅读:
- 如何修复 unix 以便可以在终端中使用箭头键?
- 我的 home/end 键不起作用(ncurses 常见问题解答)
- 为什么我的键盘不起作用?(xterm 常见问题解答)
- 键盘和功能键(术语信息手册)
- 用户定义的功能(terminfo手册,评论“k”的其他用法)
- 键盘模式(
getch
手册页)
答案2
Home 键的问题在于,物理终端和后来模拟它们的终端仿真器有两种模式:正常模式和应用程序模式,并且转义序列根据终端所处的模式而不同。Terminfo 不能很好地处理这个问题。在正常模式(又名“光标模式”)下,End 键转义序列为ESC [ F
, 在应用程序模式下ESC O F
。谷歌搜索这个问题揭示了整个混乱。
编辑来自 terminfo 来源:
VT100系列终端有光标(“箭头”)键,可以在两种不同模式下操作:光标模式和应用模式。光标模式是复位状态,并假定为正常状态。应用模式是“设置”在光标模式下,光标键传输“Esc [ {code}”序列,符合 ANSI 标准。在应用程序模式下,光标键传输“Esc O”序列。应用程序模式主要是为了帮助移植。 VT52 应用程序假设光标键通常处于光标模式,并期望 vi 等应用程序始终传输字符串,因此光标键的定义与终端传输字符串后传输的内容相匹配。如果字符串是空字符串或未定义,则假定光标键处于“光标模式”,并且光标键定义应与该假设匹配,否则应用程序可能会失败。在退出之前将字符串传输到终端。”