我需要我的终端发送一个未使用的控制字符或转义序列,该序列在所有层上均无效:被shell(bash,...)忽略,被行编辑器(readline,...)忽略,并被所有应用程序(vim,less,mutt等)。然后,我将在tmux中绑定此密钥,并在必要时使用用户定义的密钥转义序列。我使用什么控制字符或转义序列?以下是更多信息:
我希望将tmux中的Control-Shift-c键和弦绑定到一个动作,该动作会将tmux选择复制到X剪贴板选择缓冲区中。当tmux不运行时,并继续让Control-Shift-c将终端选择复制到X剪贴板选择缓冲区。终端仿真器为Control-Shift键和Control键输入生成相同的输出,请参见[1] [2]。第一步是更改此设置:
# Enable fixterms (I think) sequences for all keys:
xterm -xrm "XTerm.vt100.modifyOtherKeys: 2" -xrm "XTerm.vt100.formatOtherKeys: 1"
这指示xterm为由Control,Alt或Meta修改的所有键构造一个转义序列。据我所知,是使用原始xterm序列还是通过新的fixterms [3]规范格式化了这些转义序列。甚至tmux仅支持这些序列的一个子集[4],而不支持成熟的CSI序列解析器[5]。
根据[6],最简单的解决方法是仅Control-Shift-c发送一个fixterms序列。由于tmux不支持此序列,因此必须通过user-keys选项手动定义。它还必须绑定在tmux的根密钥表中,而不是复制模式表之一。否则,如果tmux不在复制模式下,则绑定将被忽略,并通过tmux传递给终端应用程序之一。
# Configure only Control-Shift-c to send a fixterms sequence:
xterm -xrm "XTerm*vt100.translations: #override \n\
Ctrl Shift <Key>c: string(0x1b) string ([67;6u)"
# Recognize (but don't handle) the Control-Shift-c fixterms sequence:
tmux set-option -s user-keys[0] "\e[67;6u"
# Copy the selection to the clipboard buffer only when in copy-mode. If
# there is no selection, nothing will be copied:
tmux bind-key -T root User0 if-shell -Ft= "#{pane_in_mode}"
"send-keys -X copy-pipe 'xsel -i -b'"
所有其他不支持fixterms序列的应用程序都将收到输入垃圾。更糟糕的是,未知的转义序列很可能会被误解并触发特定于应用程序的命令。最初,我考虑过使用tcgetpgrp(3)[7]来获取当前在终端中运行的命令的名称,就像#{pane_current_command}tmux [8]中的一样。
xterm <-> bash <-> command 像往常一样,Control-Shift-c的终端绑定将首先将终端的选择复制到剪贴板缓冲区。然后调用我的外部程序[9]。如果终端命令当前不是tmux,则什么也不会发生。否则,外部命令将fixterms Control-Shift-c序列写入终端的pts。当tmux接收到该序列时,它将使用自己的选择覆盖剪贴板缓冲区。
xterm -xrm "XTerm*vt100.translations: #override \n
Ctrl Shift
c: copy-selection(PRIMARY) \n
exec-formatted("~/send_fixterms_sequence_if_tmux.py") 这无法处理嵌套的终端仿真器,例如在ssh上运行tmux时-这是很常见的。
xterm <-> bash <-> ssh <-> bash <-> tmux <-> bash <-> command 这是我的难题,我目前正在考虑几种替代方法:
让终端发送控制字符而不是转义序列。始终支持控制字符。我希望那里有一个空字符,并希望Control-@(NUL或ASCII 0)有效,但是该字符会被外壳回显,并且在vim中的插入模式下具有重要作用。如果不存在这样的字符,请参阅#3。也许我可以使用一个不常见的控制字符,但它也必须配置为在所有层上不执行任何操作:xterm,bash,readline,vim等。
让终端发送未使用的或什么都不做的转义序列,而不是Control-Shift-c固定术语序列。该序列在所有层都需要被忽略:shell(bash,...)忽略,行编辑器(readline,...)忽略,所有应用程序(vim,less,mutt,...)忽略。 。参见#3。
修改终端的terminfo条目,以确保根据[10]在所有层上都至少忽略上述项之一(控制代码,标准转义序列或fixterms转义序列)。然后,将此修饰的序列结合到tmux中。
调用readline做一些神奇的事情。从长远来看,这不太可能对备用模式终端应用程序产生任何影响。
想法是,像以前一样,将终端的选择复制到剪贴板缓冲区。然后插入, 就像已经键入一样。当tmux收到时 ,它将使用自己的选择覆盖剪贴板缓冲区。任何其他应用程序都将忽略它:包括,尤其是没有任何内容打印到终端上。
xterm -xrm "XTerm*vt100.translations: #override \n\
Ctrl Shift <Key>c: copy-selection(PRIMARY) string(<STRING>)
我还计划将其扩展到gnome-terminal,因此,将转义序列或控制字符写入终端的示例pts将不胜感激。我只使用xterm作为工作示例-这个问题绝对不是特定于xterm的。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。