开发者社区> 问答> 正文

终端:发送禁止操作转义序列或控制字符

我需要我的终端发送一个未使用的控制字符或转义序列,该序列在所有层上均无效:被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的。

展开
收起
祖安文状元 2020-01-06 17:56:55 618 0
0 条回答
写回答
取消 提交回答
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载