13

I am trying to use Vim to locate and copy/paste some code I need to analyze and take notes on. I am using Debian, in a Windows WSL environment. That's what makes this tricky.

The regular "yank and put to global register" commands "+y and "*y commands didn't work.

On the other hand, the brute force approach where I just use the mouse to scrape the terminal text won't work either. Strangely, WSL terminal has mouse support, and Vim can track its movements, select in visual mode, etc. So Vim intercepts the selection command, and then there is nothing selected for ctrl-shift-c to copy into the Windows clipboard.

I know the WSL terminal supports copy and paste, and I can successfully do it if I cat my file to the screen, and copy and paste that using ctrl-shift-c and ctrl-v. But then I lose out on ease of navigation.

What's the best way to copy text out of Vim inside a WSL terminal and into the windows clipboard?

nomen
  • 3,626
  • 2
  • 23
  • 40
  • 4
    If you don't want vim to handle your mouse so you can still highlight and copy as you would anything else from the terminal, you should be able to `:set mouse=` – Christian Gibbons May 01 '20 at 22:39
  • Can you use `clip.exe` to access the clipboard from WSL? If so, select the lines visually them run `:w !clip.exe`. (Source for the `clip.exe` suggestion: https://www.raymondcamden.com/2017/10/19/copying-to-clipboard-with-windows-subsystem-for-linux) – filbranden May 02 '20 at 03:31
  • 2
    I'm using Neovim and went with the instructions on their FAQ at https://github.com/neovim/neovim/wiki/FAQ#how-to-use-the-windows-clipboard-from-wsl. Otherwise, I think [How to “copy to clipboard” in vim of Bash on Windows?](https://stackoverflow.com/questions/44480829/how-to-copy-to-clipboard-in-vim-of-bash-on-windows/61864749) can help you out. There's a few solutions that don't require installing an X server on Windows. – Andrey Kaipov May 18 '20 at 08:03
  • @nomen Check my answer. I think it is the best one so far. – 71GA Apr 05 '22 at 12:11
  • I run `vim` inside `tmux`. Tmux has a "vim" mode copy paste system where you can use vim movement commands to copy. There are config options to `tmux` that allow the use of `clip.exe` which is available under WSL to send to the clipboard. It's not perfect and actual `vim` clipboard is not connected, you have to use the `tmux` system, but you also get the advantage of using the `tmux` terminal multiplexor which gives you a consistent reliable environment everywhere. If you're interested request in a comment and I'll post an answer describing the setup. – NeilG May 13 '23 at 02:46

4 Answers4

36

Answer is, do a vim visual selection then do the command:

:'<,'>w !clip.exe

This pipes the current selection out to the shell command clip.exe, which utilizes WSL's ability to execute Windows executables (even with a pipeline). Text piped to clip.exe goes to the Windows clipboard.

Also, this command saves the whole file to the clipboard (not the requirement):

 :w !clip.exe
NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70
fencemaker
  • 461
  • 4
  • 4
  • 2
    Wow - It's really rare when I see a new user provide a correct and useful answer to an old question! Congratulations, and welcome to Stack Overflow! One small suggestion - Provide some detail on *why* this works, so people better understand the mechanics and can adjust it to other uses. I'm going to make a small edit to it to add this info. – NotTheDr01ds Jul 09 '21 at 15:11
  • For those wondering, pasting into WSL Vim from clipboard can still be done by right-clicking while in insert mode. – mbomb007 Jan 07 '22 at 16:32
  • Command equivalent for pasting is `powershell.exe Get-Clipboard`. Caveats due to UNIX and Windows convention mismatch: the output of `powershell.exe Get-Clipboard` will have carriage returns on each line, and the UNIX norm of having a trailing newline at the end of the last line is interpreted by the Windows clipboard as an extra empty line at the end. – mtraceur Feb 15 '23 at 05:08
  • So a fuller solution is probably `perl -pe 'chomp if eof' | clip.exe` for copy (to chomp off one trailing newline if there is one), and `powershell.exe Get-Clipboard | sed 's/\r$//'` for paste (to delete the spurious carriage returns at the end of each line). This is the closest we get to a translation between UNIX and Windows text semantics. (Sadly, the trailing newline workaround means there's an ambiguity/collision on the round trip - if you intentionally send data with no trailing newline to the Windows clipboard, you'll get back data with a trailing newline.) – mtraceur Feb 15 '23 at 05:34
  • this tip actually works! even though it defeats the purpose of efficiency. But obviously it only applies to local WSL vim. If you e.g. ssh somehwere then it seems you are out of luck without really awkward xserver piping. Easier to mouse select in terminal window but don't forget to disable line numbers before... – rogerovo Mar 24 '23 at 21:14
1

On Linux, Vim's clipboard support is intimately tied to X. If you want the same level of integration between WSL and the rest of Windows as you are used to in a proper Linux Box you will have to install a Windows X Server.

  1. On the Linux side, install a clipboard-enabled build of Vim. The vim-gtk package is fine.

  2. On the Windows side, install an X Server like VcXsrv (there are many alternatives, you are on your own to find the one that best suit your needs).

  3. You generally have to edit a couple of configuration files on the Linux side for your X clients to use the right X Server. What to do exactly will depend on the X Server you choose.

  4. In Vim, on the Linux side, use either "+ or "* as you would if you where on a genuine Linux box.

romainl
  • 186,200
  • 21
  • 280
  • 313
  • I did this, and it takes a really long time for vim to start up now when I run `vim somefile`. – mbomb007 Nov 24 '20 at 15:15
  • @mbomb007, FWIW, I wrote this answer a few weeks after starting a gig for $BIG_PHARMA where I had to work on one of their beaten-up Lenovos and figured out that exact setup. The whole machine was a slug, mind you, but I didn't notice any particular startup slowdown. Long startup times can be due to Vim's inability/difficulty to connect to the X server. See if you have all the config done properly. – romainl Nov 24 '20 at 17:25
1

Like romainl mentioned, clipboard is at X level. So the most important step is you need to have an X-server running on Windows, and you need to set DISPLAY variable on Linux to point to X-server. Then in neovim set clipboard=unnamedplus or vim set clipboard=unnamed to link to the system clipboard.

Follow this nice gist should make things work.

For me I use fish shell, the wsl specific logic becomes in your 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

LeOn - Han Li
  • 9,388
  • 1
  • 65
  • 59
1

I have "WSL Debian" installed and I installed a neovim package inside. PAckage installs a nvim text editor without a clipboard support. I can verify this like this:

$ 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"

Note that under Optional features included there is no +clipboard entry and this means that my nvim doesn't support clipboard out of the box.

Then I open the nvim editor and execute a command :CheckHealth to get this feedback:

## Clipboard
  - WARNING: No clipboard tool found. Using the system clipboard won't work.
    - SUGGESTIONS:
      - See |clipboard|

This tells me (a) that clipboard is not working currently and (b) to use a command :help clipboard inside the nvim to get more info. So I execute this command and I can read this:

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

This tells me that even though clipboard support was not compiled in, it is still possible to implicitly enable it if we only install e.g. xsel. So I do it:

$ sudo apt install xsel

This also tells me to put the below line in my ~/.config/nvim/init.vim:

$ set clipboard+=unnamedplus

It looks like this should already be solved, but at this point things will not yet work. Why is that? This is because xsel (as it's name implies) is a graphical application that needs X server in order to run!

So we install X server for Windows! One option is to simply install "VcXSrv"(link). This will create a "Xlaunch" launcher in the Windows start menu. We run this launcher and just click next until the "Extra settings" window. Here we make sure to check all the boxes like shown below and click "Next".

enter image description here

Now we will store our "Xlaunch" configuration by pressing "Save Configuration" and make sure to store our configuration as:

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

This will make sure that X server will start with the same configuration whenever Windows starts! Note that X server has to be running before starting the "WSL Debian".

Now we click "Finish" and for this session X server will run.

Now inside the "WSL Debian" we only have to export a DISPLAY enviromental variable which is where X server applications e.g xset will search for a working X server session. Our job is to point them to our Windows machine! So we can export DISPLAY like this:

LOCAL_IP=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
export DISPLAY=$LOCAL_IP:0

If you want you can add these two lines in the ~/.bashrc file on "WSL Debian" so that they will always be exported when you open an interactive terminal.

Now everything should work.

71GA
  • 1,132
  • 6
  • 36
  • 69