QQA: 如何从远程运行的 Vim 中复制内容
我们常常会用 ssh
登录远程机器,并在在其中 vim
命令编辑查看文件。一个常见的问题是如何 无缝
把选中的内容复制到本地的剪贴板呢?
步骤
-
本地需要一个支持 OSC 52 的终端
-
Linux 下的 xterm, 设置
disallowedWindowOps: 20,21,SetXprop
-
Mac 下的 iterm2,勾选
Applications in terminal may access clipboard
-
Linux 下的 xterm, 设置
- 在远程机器上安装 neovim,它允许我们自定义如何复制粘贴
-
把 clipboard-provider
脚本放在PATH
下。 -
在 vimrc 中添加如下配置:
if executable('clipboard-provider') let g:clipboard = { \ 'name': 'myClipboard', \ 'copy': { \ '+': 'clipboard-provider copy', \ '*': 'env COPY_PROVIDERS=tmux clipboard-provider copy', \ }, \ 'paste': { \ '+': 'clipboard-provider paste', \ '*': 'env COPY_PROVIDERS=tmux clipboard-provider paste', \ }, \ } endif
尝试在 ssh 中打开 neovim,通过 "+y
来复制内容,预期本地能直接粘贴这些内容!
原理
OSC 52
OSC 52 是 xterm
的一个特性,许多终端也支持。它能识别命令行输出中的一些特定格式的内容,并将其中的内容解析后设置为系统剪贴板的内容。具体来说, 这个特性
能解析的格式如下:
OSC 52 ; Pc ; Pd ST
-
前缀 OSC 是
\e]
-
其中的
Pc
用于选择使用哪个剪贴板,我们选择主剪贴板c
-
其中的
Pd
是 base64 编码后的内容,例如hello
编码为aGVsbG8=
-
ST
指的是\a
我们可以通过执行命令 echo -e '\e]52;c;aGVsbG8=\a'
,然后看粘贴的内容是否为 hello
来判断当前终端是否支持 OSC 52.
注意:这个特性有潜在的安全问题,所以理论上开启后不要执行你不信任的程序。
clipboard-provider
clipboard-provider 脚本的作用是将输入的内容尝试“粘贴”到 tmux 的 buffer 中、系统的剪贴板中。这个脚本可以独立于 neovim 使用。如可以尝试把远程的文件复制到剪贴板中: cat hello.txt | clipboard-provider copy
。
g:clipboard
在 neovim 中输入 :help g:clipboard
可以看到相关的说明。简单地说,它允许我们指定,当复制内容到 +
或 *
寄存器时,执行什么命令。上面的设置其实就是调用了 clipboard-provider copy
来将内容复制 tmux 及系统剪贴板中。
支持 tmux
我个人一般是在 SSH 中运行 tmux,再在 tmux 中运行 vim 等命令。幸运的是 tmux 也支持 OSC 52. 只需要在 ~/.tmux.conf
中添加:
set -g set-clipboard on
现在还缺失的一个功能是远程粘贴的时候也能打通剪贴板,这个还没研究出来,就先不说了。