如何在WSL中从Vim复制/粘贴

15

我想使用Vim定位并复制/粘贴需要分析和记录的代码。 我正在使用Debian,在Windows WSL环境中进行操作,这使得问题更加棘手。

然而,常规的“yank and put to global register”命令"+y"*y无法正常工作。

另一方面,我不能采用使用鼠标选择终端文本的笨拙方法。奇怪的是,WSL终端支持鼠标,而Vim可以跟踪其移动、在可视模式下选择等。因此,Vim截取了选择命令,但没有选中任何内容可以使用ctrl-shift-c复制到Windows剪贴板中。

我知道WSL终端支持复制和粘贴,并且如果我将文件cat到屏幕上,就可以成功地进行复制和粘贴,使用ctrl-shift-c和ctrl-v。但是,这样我就失去了便捷的导航功能。

在WSL终端内部从Vim复制文本并将其粘贴到Windows剪贴板中的最佳方法是什么?


4
如果你不希望Vim处理你的鼠标,因此你仍然可以像从终端中复制其他内容一样进行高亮和复制操作,那么你应该能够使用命令 :set mouse= - Christian Gibbons
你能否在WSL中使用clip.exe来访问剪贴板?如果可以,选择要复制的行,然后运行:w !clip.exe。(clip.exe建议来源:https://www.raymondcamden.com/2017/10/19/copying-to-clipboard-with-windows-subsystem-for-linux) - filbranden
2
我正在使用Neovim,并按照他们在https://github.com/neovim/neovim/wiki/FAQ#how-to-use-the-windows-clipboard-from-wsl上的常见问题解答中的说明进行操作。否则,我认为[如何在Bash on Windows的vim中“复制到剪贴板”?](https://dev59.com/olcP5IYBdhLWcg3wY5CJ#61864749)可以帮助你。有一些解决方案不需要在Windows上安装X服务器。 - Andrey Kaipov
@nomen请检查我的答案。我认为这是迄今为止最好的答案。 - 71GA
我在tmux中运行vim。Tmux有一个“vim”模式的复制粘贴系统,您可以使用vim移动命令进行复制。有一些配置选项可以让tmux使用在WSL下可用的clip.exe发送到剪贴板。它并不完美,实际上vim剪贴板没有连接,您必须使用tmux系统,但您也可以利用tmux终端多路复用器的优势,在任何地方都可以获得一致可靠的环境。如果您感兴趣,请在评论中请求,我将发布一个描述设置的答案。 - NeilG
4个回答

39
回答是,进行vim视觉选择,然后执行以下命令:
:'<,'>w !clip.exe

这将当前所选内容输出到 shell 命令clip.exe,它利用了 WSL 执行 Windows 可执行文件的能力(即使使用管道)。文本被传输到clip.exe的剪贴板是Windows剪贴板。

此外,这个命令会将整个文件保存到剪贴板中(不是必需的):

 :w !clip.exe

2
哇 - 当我看到一个新用户对一个旧问题提供正确和有用的答案时,这真的很少见!恭喜你,并欢迎来到Stack Overflow!一个小建议 - 提供一些关于为什么这个方法有效的细节,这样人们就能更好地理解其机制并将其调整到其他用途。我会对它进行小小的编辑,以添加这些信息。 - NotTheDr01ds
1
对于那些想知道的人,从剪贴板粘贴到WSL Vim仍然可以通过在插入模式下右键单击来完成。 - mbomb007
粘贴的命令等效于 powershell.exe Get-Clipboard。由于 UNIX 和 Windows 约定不匹配,需要注意以下事项:powershell.exe Get-Clipboard 的输出每行都会有回车符,并且 UNIX 以在最后一行末尾添加换行符为规范,而 Windows 剪贴板将其解释为额外的空行。 - mtraceur
因此,更完整的解决方案可能是 perl -pe 'chomp if eof' | clip.exe 用于复制(如果有一个尾随换行符,则去除它),以及 powershell.exe Get-Clipboard | sed 's/\r$//' 用于粘贴(删除每行末尾的多余回车符)。这是我们在UNIX和Windows文本语义之间得到的最接近的翻译。(遗憾的是,尾随换行符的解决方法意味着在往返过程中存在歧义/冲突 - 如果您有意将没有尾随换行符的数据发送到Windows剪贴板,则会收到带有尾随换行符的数据。) - mtraceur
这个技巧确实有效!尽管它违背了效率的目的。但显然,它只适用于本地WSL vim。如果你例如ssh到某个地方,那么似乎你没有运气,除非使用非常笨拙的xserver管道。在终端窗口中更容易鼠标选择,但不要忘记在之前禁用行号... - rogerovo

1

我已经安装了"WSL Debian",并在其中安装了neovim软件包。该软件包安装了一个不支持剪贴板的nvim文本编辑器。我可以通过以下方式进行验证:

$ nvim --version

NVIM 0.1.7
Build type: None
Compilation: /usr/bin/cc -g -O2 -fdebug-prefix-map=/build/neovim-HEl3mV/neovim-0.1.7=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -DDISABLE_LOG -Wconversion -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1  -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wvla -fstack-protector-strong -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -DHAVE_CONFIG_H -D_GNU_SOURCE -I/build/neovim-HEl3mV/neovim-0.1.7/build/config -I/build/neovim-HEl3mV/neovim-0.1.7/src -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/build/neovim-HEl3mV/neovim-0.1.7/build/src/nvim/auto -I/build/neovim-HEl3mV/neovim-0.1.7/build/include
Compiled by pkg-vim-maintainers@lists.alioth.debian.org

Optional features included (+) or not (-): +acl   +iconv    +jemalloc +tui
For differences from Vim, see :help vim-differences

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/share/nvim"

请注意,在“包括的可选功能”下没有“+clipboard”条目,这意味着我的nvim默认情况下不支持剪贴板。然后我打开nvim编辑器并执行命令“:CheckHealth”以获取以下反馈:
## Clipboard
  - WARNING: No clipboard tool found. Using the system clipboard won't work.
    - SUGGESTIONS:
      - See |clipboard|

这告诉我 (a) 剪贴板当前不起作用,(b) 要在 nvim 中使用命令 :help clipboard 获取更多信息。所以我执行了这个命令,然后可以看到这个:

Clipboard access is implicitly enabled if any of the following clipboard tools
are found in your `$PATH`.

  - xclip
  - xsel (newer alternative to xclip)
  - pbcopy/pbpaste (Mac OS X)
  - lemonade (for SSH) https://github.com/pocke/lemonade
  - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/

The presence of a suitable clipboard tool implicitly enables the '+' and '*'
registers.

If you want to ALWAYS use the clipboard for ALL operations (as opposed
to interacting with the '+' and/or '*' registers explicitly), set the
following option:

    set clipboard+=unnamedplus

这告诉我,即使没有编译剪贴板支持,只需安装例如 xsel,就可以隐式启用它。因此我这样做:

$ sudo apt install xsel

这也告诉我要将以下行放入我的~/.config/nvim/init.vim文件中:
$ set clipboard+=unnamedplus

看起来这个问题应该已经解决了,但是此时事情仍然不起作用。为什么?这是因为xsel(正如其名称所示)是一个需要X服务器才能运行的图形应用程序!

所以我们要为Windows安装X服务器!一种选择是简单地安装"VcXSrv"链接)。这将在Windows开始菜单中创建一个"Xlaunch"启动器。我们运行此启动器,直到"Extra settings"窗口,然后只需像下面展示的那样勾选所有框并点击"Next"

enter image description here

现在我们将通过按"Save Configuration"来存储我们的"Xlaunch"配置,并确保将我们的配置存储为:

C:\Users\<Username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\config.xlaunch

这将确保每次Windows启动时,X服务器都会以相同的配置启动!请注意,在启动“WSL Debian”之前,必须运行X服务器。
现在我们点击“完成”,此会话将运行X服务器。
现在在“WSL Debian”内部,我们只需要导出一个DISPLAY环境变量,这是X服务器应用程序(例如xset)搜索可工作的X服务器会话的位置。我们的任务是将它们指向我们的Windows机器!因此,我们可以像这样导出DISPLAY:
LOCAL_IP=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
export DISPLAY=$LOCAL_IP:0

如果您想要的话,可以在“WSL Debian”上的~/.bashrc文件中添加这两行内容,这样它们将始终在打开交互式终端时被导出。

现在一切都应该正常工作了。


1

在Linux上,Vim的剪贴板支持与X紧密相关。如果您想要在WSL和Windows的其余部分之间获得与适当的Linux Box中所使用的相同级别的集成,则必须安装Windows X Server。

  1. 在Linux侧,安装启用剪贴板的Vim版本。 vim-gtk软件包很好。

  2. 在Windows侧,安装像VcXsrv这样的X服务器(有许多替代方案,您需要自行找到最适合您需求的)。

  3. 通常,您需要在Linux侧编辑一些配置文件,以便您的X客户端使用正确的X服务器。具体操作将取决于您选择的X服务器。

  4. 在Linux侧的Vim中,使用"+"*,就像您在真正的Linux Box上一样。


我这样做了,现在当我运行 vim somefile 时,vim启动需要很长时间。 - mbomb007
@mbomb007,顺便说一下,我在开始为$BIG_PHARMA工作几周后写了这个答案,我不得不在他们磨损的Lenovo上工作,并找出了确切的设置。整个机器都很慢,但我没有注意到任何特定的启动减速。长时间的启动可能是由于Vim无法/难以连接到X服务器。看看你是否已经正确完成了所有配置。 - romainl

1

就像romainl提到的那样,剪贴板在X级别上。因此,最重要的步骤是您需要在Windows上运行X服务器,并且您需要设置Linux上的DISPLAY变量以指向X服务器。然后在neovim中使用set clipboard=unnamedplus或vim中的set clipboard=unnamed来链接到系统剪贴板。

遵循this nice gist应该可以使事情正常工作。

对我来说,我使用fish shell,wsl特定逻辑将出现在您的config.fish中。

if uname -r | grep 'microsoft' > /dev/null 
  set -l LOCAL_IP (cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
  set -xg DISPLAY $LOCAL_IP:0
end


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接