在 xterm 中,当我按键盘上的 HOME 键时,它通常会发送,^[[H
但是当我打开时emacs -nw
,它会更改为^[OH
; 这些分别是home
和khome
。我在尝试构建自己的终端时发现它^[[H
在 emacs 中不起作用。但是,我无法弄清楚是什么导致 xterm (或 emacs)改变其行为。
此外
home
“应该”对应于和的键khome
(我通常使用的 home 键,以及关闭数字锁定的键盘上的 1) - 在我尝试过的每个终端上始终执行相同的操作,即使 xev 显示它们是不同的,所以对于其余的对于这个问题,我会将它们视为同一件事。- 它似乎与 pty 设置无关。我曾经
stty -g
在打开 emacs 的情况下复制设置,然后通过cat -v
运行应用它们,但我仍然得到非 emacs 的行为。(下面的演示) - bash 的 readline 似乎比 emacs 和/或读取 TERM 变量更容易接受,因为无论我尝试什么终端,HOME 总是在 bash 中工作
这是我的实验:
xterm
获取终端信息:
$ tty
/dev/pts/1
$ echo $TERM
xterm
$ infocmp $TERM | grep home
el1=\E[1K, flash=\E[?5h$<100/>\E[?5l, home=\E[H,
kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~,
尝试按 HOME 键,然后按返回cat -v
,然后退出
$ cat -v
^[[H
^[[H
^C
打开 emacs
$ emacs -nw
尝试主页键的行为(它有效 - 我不会发布视频)
使用C-q
来查看密钥发送的内容:
[
同时在另一个终端(不必是 xterm)中,复制 emacs pty 设置:
$ emacs_settings=$(stty -F /dev/pts/1 -g)
$ echo $emacs_settings
4001:1:bf:a31:7:7:7f:15:4:0:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:
然后退出 emacs 并cat -v
重新开始
$ cat -v
然后返回第二个终端 - 将 xterm pty 设置回 emacs 使用的设置
$ stty -F /dev/pts/1 $emacs_settings
然后在 xterm 中再次按 home:(然后按 return 并退出)
$ cat -v
^[[H^M
它与 emacs 之外的代码一样,是home
代码,而不是khome
有人在 emacs 中插入的代码。
现在,如果您在家中尝试此操作,并且想要退出cat -v
,则需要使用 ctrl+G 而不是 ctrl+C,因为 emacs 设置会更改一些键。这证明设置有效。您还可以看到退出行末尾没有 ^G,但有一个回车符 - 我猜是因为回显设置发生了变化,并且处于原始模式。
如果您好奇的话,这里是人类可读的 emacs pty 设置。
$ stty -F /dev/pts/1 -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^G; quit = ^G; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = <undef>; stop = <undef>; susp = <undef>;
rprnt = <undef>; werase = <undef>; lnext = <undef>; discard = <undef>; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig -icanon -iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
其他终端
linux
$ infocmp linux | grep home
home=\E[H, hpa=\E[%i%p1%dG, ht=^I, hts=\EH, ich=\E[%p1%d@,
kf8=\E[19~, kf9=\E[20~, khome=\E[1~, kich1=\E[2~,
这个不太容易截图(我可以拍照,但我没有)
总结是 - 无论您是否在 emacs 中,HOME 键都会khome
从终端设置发送,并且它始终在 emacs 中起作用。
MATE 终端 ( xterm-256color
)
$ echo $TERM
xterm-256color
$ infocmp $TERM | grep home
el1=\E[1K, flash=\E[?5h$<100/>\E[?5l, home=\E[H,
kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~,
$ cat -v
^[[H
^[[H
^C
但它再次发送到^[OH
emacs 内部!所以他们又是不同的。我不知道我之前是怎么错过这个的。我猜 MATE 终端完全实现了 xcode 的功能,或者使用了一些相同的组件。
另一方面:
超 (xterm-256color
)
在这种情况下,他们只是khome
一直发送,并且 HOME 键似乎仍然按照您期望的方式工作。
$ echo $TERM
xterm-256color
$ cat -v
^[OH
^[OH
^C
$ emacs -nw
$ # ... ^[OH again
tmux(在 MATE 终端中)screen
我不知道 tmux 何时设置TERM
为screen
以及何时将其设置为tmux
,但今天在这台计算机上,在该主机终端中,它是screen
。
$ echo $TERM
screen
$ infocmp $TERM | grep home
enacs=\E(B\E)0, flash=\Eg, home=\E[H, hpa=\E[%i%p1%dG,
khome=\E[1~, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
$ cat -v
^[[1~
^[[1~
^C
$ emacs -nw
$ # also ^[[1~ with C-q inside emacs
围捕
- 有些终端只是
khome
一直发送,而其他终端则设法khome
在 emacs 内部发送,home
其余时间都发送。 khome
两者home
都适用于 bash readline,但仅khome
适用于 emacs - 或者只有一个固定的可在 emacs 中使用的 home 键列表(我说的是默认配置) - 我倾向于固定列表,因为我无法获取 emacs通过改变来改变行为TERM
大问题
xterm(和 MATE 终端)如何设法更改在 emacs 打开时发送的代码。
以下是我能想到的一些猜测:
a) xterm 有一个关于 emacs 的特殊规则 b) emacs 有一个关于 emacs 的特殊规则xterm
c) emacs 确实会更改终端设置来导致这种情况,但无论该设置是什么,cat
如果您尝试让 cat 使用该设置,它都会不断地更改回来
值得一提的小问题
- 为什么看起来像的键不对应
home
并khome
发送相应的值? - emacs(默认情况下)是否根据 改变其行为
TERM
?
您指的是键盘应用程序模式,该模式记录在XTerm 控制序列中:
并通过以下方式激活/停用
DECCKM
:通过终端描述
smkx/rmkx
中的功能(您可以使用 infocmp 查看):(非屏幕应用程序通常不会初始化终端,全屏应用程序通常会初始化终端——忽略每种情况下的硬编码内容)。