我需要我的终端发送一个未使用的控制字符或转义序列,该序列在所有层上均无效:被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]来获取当前在终端中运行的命令的名称,就像tmux [8]中的#{pane_current_command}
一样。
xterm <-> bash <-> command
Control-Shift-c的终端绑定将首先照常将终端的选择复制到剪贴板缓冲区;然后调用我的外部程序[9]。如果终端命令当前不是tmux,则什么也不会发生。否则,外部命令将Fixterms Control-Shift-c序列写入终端的pts
。当tmux接收到该序列时,它将使用自己的选择覆盖剪贴板缓冲区。
xterm -xrm "XTerm*vt100.translations: #override \n\
Ctrl Shift <Key>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做一些神奇的事情。长远来看,因为这不太可能对备用模式终端应用程序产生任何影响。
想法是像以前一样,将终端的选择复制到剪贴板缓冲区。然后插入<STRING>
,就像已经键入一样。当tmux收到<STRING>
时,它将使用自己的选择覆盖剪贴板缓冲区。任何其他应用程序都将忽略它:包括,尤其是没有任何内容打印到终端上。
xterm -xrm "XTerm*vt100.translations: #override \n\
Ctrl Shift <Key>c: copy-selection(PRIMARY) string(<STRING>)
我还打算将其扩展到gnome-terminal,因此将转义序列或控制字符写入终端的pts
的示例将不胜感激。我只使用xterm作为工作示例-这个问题绝对不是xterm特定的。
编辑,新思路: SSH提供了自己的终端仿真器,或者至少与pts
对挂钩[11]。这是否意味着它可以处理传入的转义序列,并可能运行外部远程命令,例如使用tcgetpgrp
的命令?还是那是一种不安全感?与其配置可能无休止的终端应用程序系列以忽略转义序列,不如像tmux那样仅配置SSH。
答案 0 :(得分:0)
所有可用序列对于接收它的应用程序都可能看起来像某种密钥(例如0是C- @和C-Space),没有保证应用程序可以忽略的序列。
如果我是我,我只是发送F20或类似内容的转义序列,然后将该键绑定在您经常使用的其他应用程序中什么也不做。