在 tmux 复制模式下运行任意命令

在 tmux 复制模式下运行任意命令

当我在 tmux 复制模式下选择某些文本时,我可以在不使用预定义的键绑定的情况下对所选文本调用系统命令吗?

例如,我可以调用pastebin将选定的文本发送到 Pastebin,或调用wc来计算行数。我尝试了以下方法,但没有成功:

  1. 选择文本c-b [
  2. 这两种方式都尝试过:
    1. :,希望进入命令模式 - 不起作用,因为这会提示“转到行”
    2. c-b :copy-pipe wc- 不起作用,因为它说复制管道是未知命令

注意:我使用的是 Tmux 3.1c

我知道像这样的解决方案这个。但是,这需要我预见每个用例并为我将执行的每个可能的命令预定义键绑定。

在 Vim 中,这是支持的,即选择文本,然后:!<system_command>将文本发送到system_command.

答案1

您已经接近目标了;至少是这样的。复制模式命令需要通过 发送sendkeys -X

因此,要将选定的文本通过管道传递给命令,将是:

  • Prefix :
  • send-keys -X copy-pipe "wc"

但是,Tmux 不显示任何copy-pipe地方的输出。使用run-command,输出显示在复制缓冲区中。对于copy-pipe,它似乎只是被吞噬了。您在另一个答案中链接到的示例只是保存了一个缓冲区,因此不需要输出/反馈。

对于 a 来说wc,这不太有用。我猜测 的输出pastebin是一个非常有用的 URL ...

我发现的最简单的替代方案开始变得混乱,尤其因为你想用任意命令来做到这一点:

  • Prefix :
  • send-keys -X copy-selection-no-clear ; run-shell "tmux show-buffer | wc"

请注意,没有错误检查来确定是否选择了某些内容。它将简单地show-buffer在最新的缓冲区上运行。

恕我直言,一个可能更好的选择

由于 Vim 擅长此用例,因此请使用它。设置一个键绑定,在vim使用进程替换时打开回滚缓冲区。

对于在 shell 中测试(已测试):

tmux bind-key -T copy-mode v new-window -d -n scrollback "vi <(tmux capture-pane -p -S - -E -)" \\\; run-shell "sleep 1" \\\; select-window -t scrollback

或者在您的配置中(未经测试):

bind-key -T copy-mode v new-window -d -n scrollback "vi <(tmux capture-pane -p -S - -E -)" \; run-shell "sleep 1" \; select-window -t scrollback

Hacky,是的,您可能需要增加sleep更大的缓冲区——我还没有测试过。可能有更好的方法,但这就是我想到的。

此外,您还会丢失 ANSI 颜色代码,但您也许可以使用以下命令来处理(如果您关心的话):安西ESCVIM 扩展,以及添加-ecapture-buffer(以将 ANSI 代码保留在缓冲区输出中)。

答案2

基于NotTheDr01ds回答,我得到了完整的解决方案:

bind-key -T copy-mode   !  command-prompt -p "cmd:" "send-keys -X copy-selection-no-clear \; run-shell \"tmux show-buffer | %1\" "
bind-key -T copy-mode-vi   !  command-prompt -p "cmd:" "send-keys -X copy-selection-no-clear \; run-shell \"tmux show-buffer | %1\" "

用法:选择一些文本然后按!。它将提示您输入要运行的 shell 命令。选定的文本将作为标准输入提供给 shell 命令。 shell 命令的标准输出将显示回 tmux 窗格。

感谢 NotTheDr01ds 的精彩提示!

相关内容