68

To get this off the table now and avoid any confusion ... This is for Linux running in Windows 10(ubunutu), also known as WSL. Its not the same as cygwin and windows or stand alone linux. It is it's own beast.

So please keep the above in mind before I am referenced with all the articles I have already read or comment that this has been asked before.

Does anyone know how to make the copy and paste work off of the windows clipboard OR the WSL Ubuntu Linux emulation? I am using set clipboard=unnamedplus. It's not working, not matter what combinations I use like yy, "+yy, etc.

Yes, it's vim-gtk with +xterm_clipboard support.

dman
  • 744
  • 2
  • 7
  • 11
  • If you're running Win10 pre-1709, then WSL is beta software obtained through the developer channel. Since then, the official release is Ubuntu (or OpenSUSE) available through Linux on Windows from MS Store. Despite your clarification, it's not clear which you're running. That said, I've found that the standard `cmd` terminal clip-board handling seems to work on both. – AFH Feb 02 '18 at 16:57
  • No, this is most recent...non beta..from the store. I just installed it 3 days ago. I can't get vim to use the clipboard (rather it be windows or linux ...not sure which would be used in the unique WSL case). – dman Feb 02 '18 at 16:59
  • 1
    It works for me in 1709: I have configured the bash terminal for Quick Edit mode and I use click and drag to select, right-click to copy selection and again to paste. – AFH Feb 02 '18 at 17:11
  • @AFH just to confirm, you are able to yank contents in vim using the vim yank command(ie: `yy`), have the yanked contents go to the clipboard, and paste from the clipboard using vim's paste (ie `pp`) in a separate vim session? – dman Feb 04 '18 at 03:55
  • That seems to work: I typed `5yy` to copy 5 lines, restarted `vim`, and `p` pasted the 5 lines. – AFH Feb 04 '18 at 12:09
  • @AFH I have that behavior also. But it's a different behavior if you have two separate vim sessions at the same time and you try to go back and forth with the pasting. – dman Feb 07 '18 at 18:17
  • Do you mean in separate `bash` windows? I'm not surprised if this is the case, as the two sessions would likely be independent of each other. But using Windows copy and paste will work between them. – AFH Feb 07 '18 at 21:15
  • 1
    @AFH yep... I used to be able to do this with two separate cygwin sessions using the windows clipboard registers. Any ideas on how to do it in WSL? – dman Feb 07 '18 at 22:42
  • Same way, as per my second comment. The paste can be done in any window, terminal-based or otherwise. – AFH Feb 07 '18 at 23:13
  • 1
    perhaps this does it? https://vi.stackexchange.com/q/15182/71 – Christian Brabandt Mar 13 '18 at 16:00
  • To take this to a more general level, I think the gist of this would be "paste into vim from windows clipboard", not the reverse. Like if I were to copy a snippet for a config in windows browser, then try to paste that snippet into WSL term with vim open, nothing seems to work. – dhaupin Apr 10 '18 at 23:49

12 Answers12

41

(Edit: Oct 2020) For 2-way clipboard on neovim, I have been using win32yank for several months with no issues. Put win32yank.exe somewhere in your path on Linux (anywhere should be fine), and add the following to your init.vim.

set clipboard+=unnamedplus
let g:clipboard = {
          \   'name': 'win32yank-wsl',
          \   'copy': {
          \      '+': 'win32yank.exe -i --crlf',
          \      '*': 'win32yank.exe -i --crlf',
          \    },
          \   'paste': {
          \      '+': 'win32yank.exe -o --lf',
          \      '*': 'win32yank.exe -o --lf',
          \   },
          \   'cache_enabled': 0,
          \ }

(Original answer) If you just want to yank from VIM to Windows, for WSL2 and Ubuntu 20.04, this answer on Reddit worked perfectly for me with standard VIM and standard WSL2 Ubuntu.

Put the following in your .vimrc (at the bottom, for example):

" WSL yank support
let s:clip = '/mnt/c/Windows/System32/clip.exe'  " change this path according to your mount point
if executable(s:clip)
    augroup WSLYank
        autocmd!
        autocmd TextYankPost * if v:event.operator ==# 'y' | call system(s:clip, @0) | endif
    augroup END
endif
AntonOfTheWoods
  • 541
  • 4
  • 8
  • 1
    Also works fine on Debian with WSL1 – PabTorre Aug 28 '20 at 23:58
  • 2
    I didn't really need to do the let g:clipboard thing. neovim-0.5.0+ubuntu2+git202105110234-133351cbf-d569569c9 supported it out of the box. :checkhealth returns "OK: Clipbard tool found: win32yank". It's also worth mentioning win32yank is something you install on the Windows side, not the WSL side (choco install win32yank) –  May 18 '21 at 13:45
  • 1
    @3nuc, you don't need to "install" win32yank. It is a self-contained binary. It should be executable from Linux and doesn't *need* to be available for Windows *at all*. I guess your Windows choco bin path is added to the WSL path, hence why doing it your way would work. It might even be more practical but it is not "something you install on the Windows side" (at least not something that needs to be anyway). – AntonOfTheWoods May 24 '21 at 04:03
  • thanks for the snippet. it's working but not if Vim open in tmux. Any suggestion ? Thank you – xaa Aug 26 '21 at 21:22
  • @xaa, this has been working for me with tmux-yank since the beginning, try that. – AntonOfTheWoods Aug 31 '21 at 02:06
  • `10 lines yanked Error detected while processing function provider#clipboard#Call[6]..3[15]..30_try_cmd: line 1: E475: Invalid value for argument cmd: 'win32yank.exe' is not executable` I'm getting these errors when trying to copy. What do you mean "place win32yank anywhere" ? You probably meant to place `win32yank.exe` into `/bin/win32yank.exe` – Nick May 05 '22 at 15:08
  • @Nick, "Put win32yank.exe somewhere in your path on Linux". The "anywhere" after that means "in any of the locations on your path". `/bin/win32yank.exe` is probably on your path but, again, anywhere on your path should be fine, as long as `win32yank.exe` file has the +x permission. Many people have a `bin` directory in their home folder that they add to their path for custom/non-system utilities such as this. I always have. – AntonOfTheWoods May 07 '22 at 02:31
  • @walnut_salami, that's a good tip. I've proposed an edit to AntonOfTheWoods' answer that mentions Neovim's autodetection. – Esteis Aug 11 '22 at 08:54
  • @Esteis the comment you are referring to had some incorrect statements so I disregarded it entirely. I no longer have a WSL handy but the above doesn't only do detection, it also configures the clipboard so it is fully integrated. You may not want that but I think most do, so I'm not sure your change is warranted. neovim also uses init.vim, not a file named .vimrc. – AntonOfTheWoods Aug 13 '22 at 01:57
  • Hi AntonOfTheWoods, that's fine. – Esteis Aug 14 '22 at 13:09
  • [oops hit Enter too soon] Hi, AntonOfTheWoods! that's fine, you're right, I overlooked `set clipboard+=unnamedplus`, which lets `y` and `p` use the clipboard; would be a shame to miss that out. I can, however, confirm (I tried it) that when `win32yank.exe` is on the WSL $PATH, Neovim autoconfigures the `*` and `+` registers to use win32yank (and therefore the Windows clipboard). See the [NeoVim docs on clipboard-tool](https://neovim.io/doc/user/provider.html#clipboard-tool). Thanks for the feedback. If I get around to it, I'll propose another edit later that is hopefully more complete/correct. – Esteis Aug 14 '22 at 13:30
  • @Esteis, actually I wrote neovim because that is what I was using at the time and was too lazy to check but I'm pretty sure those instructions will also work for vim OOTB (minus the init.vim). I'm not certain vim will autosetup the extra registers, so it would be a shame to remove the instructions if it doesn't. – AntonOfTheWoods Aug 15 '22 at 14:52
  • Is there a way I could map to y instead of y? – Dennis Feb 17 '23 at 03:36
21

This solution worked for me, thanks to github user robbiev.

For completion this is an outtake from his answer:

  1. Install VcXsrv (if it starts after installing, stop it).
  2. Start it using the newly installed program XLaunch (search in the start menu).
  3. Go with all the defaults options, and ensure the clipboard options are checked.

  4. At the end, save the configuration to a file, config.xlaunch (use that to start it from now on).

  5. Put export DISPLAY=localhost:0.0 in your .bashrc in bash for Windows and run source ~/.bashrc in any open terminal.

  6. Ensure vim is installed using clipboard support. vim --version | grep clipboard should say +clipboard, not -clipboard. Also if you run the ex command :echo has('clipboard') in vim and it says 0 it does not have clipboard support compiled in.

  7. If you don't have clipboard support, install a vim package compiled with clipboard support, e.g. apt-get install vim-gtk.

  8. Now you can access the Windows system clipboard via "*p and "*y, or set it to default by putting set clipboard=unnamed in your .vimrc file.

As robbiev mentions you should now also be able to use the Windows clipboard from remote machines using SSH X forwarding.

Aerows
  • 311
  • 2
  • 4
  • 20
    The joy when you (me) face with same problem 4 months later, google it and your (mine) past self helps you fix it! – Aerows Nov 20 '18 at 17:06
  • 1
    Windows 11 WSL is pre-configured with an X server, which reduces the above steps to just `sudo apt install vim-gtk`. – daviewales May 24 '23 at 00:09
14

You can right click the terminal then in the options box check CTRL + SHIFT + C/V for copy paste operations through the terminal.

WSL Ubuntu Terminal

errorprone
  • 249
  • 2
  • 2
5

MAY 2023 SOLUTION

The following worked for me (2023/05/15, WSL Ubuntu 20.04.5 LTS):

If you don't have clipboard support, install a vim package compiled with clipboard support:

sudo apt-get install vim-gtk

(This is similar to Aerows answer but you don't need VcXsrv)

3

If you are using vim(or neovim), maybe you should know ANSI OSC52 that is a standard which trys to solve this "copy/paste" problem(in specific cases, e.g. in a SSH terminal).

Then here's on useful plugin vim-oscyank which implements this standard and what you have to do is just install this plugin and set a keymapping for it. You should definitely give it a try.

d0zingcat
  • 131
  • 3
2

If you have enabled the QuickEdit Mode, you can just select the text with your mouse and right click to copy it into the clipboard.

For enabling the QuickEdit Mode, just right-click on the console windows on top and select Properties (and/or Default), then tick QuickEdit Mode.

EDIT: Out-of-the-box, it is not possible to copy from VIM into Windows clipboard currently. However, on a GitHub-Issue within the WSL repository, some guys seem to have found a way to do that using Xming or VcXsrv respectively: https://github.com/Microsoft/WSL/issues/892#issuecomment-275873108.

EDIT2: Another try using .vimbuffer: https://stackoverflow.com/questions/44480829/how-to-copy-to-clipboard-in-vim-of-bash-on-windows

dwettstein
  • 133
  • 8
2

A partial solution through ConEmu

Not sure why nobody mentioned ConEmu. It can at minimum handle one-half of the clipboard issue:

  • To paste Windows clipboard stuff into WSL, normal Ctrl + V will get things right.

    • One perk is that: if one is to copy an absolute path in Windows, when pasting in ConEmu, c:/users/name will be transcribed into /mnt/c/users/name. This is runnable through WSL natively.
  • To copy from WSL, for now, I would still have to use my house cursor. It works more than 90% of the times.

Per my use case, I don't tend to copy from WSL a lot; and have been enjoying the pasting-help by ConEmu a lot.

llinfeng
  • 1,173
  • 2
  • 15
  • 36
  • I did find that you have to use a different terminal besides the default WSL terminal that comes from installing the your distro of choice. Thanks for leading me in the right direction. I use [Terminus](https://eugeny.github.io/terminus/) in case anyone was wondering. Works great as a WSL terminal. – Charles Williams Apr 06 '20 at 19:54
  • 1
    I now use [`wsltty`](https://github.com/mintty/wsltty) as the emulator, which even supports mouse-click events. It is my #1 recommendation for now, after 2+ years with WSL :) – llinfeng Apr 07 '20 at 03:50
2

Here's a simple 2023 solution with no third-party software:

Updated Solution

Mapping
vnoremap <C-c> y:!echo <C-r>=escape(substitute(shellescape(getreg('"')), '\n', '\r', 'g'), '#%!')<CR> <Bar> clip.exe<CR><CR>
Usage

Highlight text in visual mode (visual, visual line, or visual block) and pressCtrl-c.

Explanation

First, yank the selection. Then insert it into the command line using getreg('"'). Then, use shellescape to handle the quotations. Then substitute out the newline characters with carriage returns using substitute. Then use escape to convert any !, %, or # characters to \!, \%, or \#, respectively. Finally, insert all that and use <Bar> clip.exe to pass the entire thing to clip.exe.

Old Solution that Only Copied Whole Lines

Mapping
vnoremap <C-c> ::w !clip.exe<CR><CR>
Usage

Highlight text in visual mode and pressCtrl-c.

Explanation

: gets you into command mode (which will give you '<,'>). Then :w will pass the selection to a command. Using ! means it's an external command, which is clip.exe here. Finally, you need 2 <CR>s: one to execute the command and one get out of the subshell.

nullromo
  • 153
  • 6
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 16 '23 at 17:59
  • 1
    @Community I wanted to keep the answer concise and I included multiple links to source material. I feel that the answer is very clear already. Since there are already many wordy answers on this question, my goal was to write one that's much easier to understand, hence the simplicity and brevity. – nullromo Jan 16 '23 at 18:03
  • 2
    @nullromo I agree - I think the reviewer is in error. You did include the links to the background material, which I believe is sufficient. That said, I did remove the heading, since that's semantically incorrect here. It comes across as being designed to call attention to your answer, which isn't necessary. – NotTheDr01ds Jan 16 '23 at 19:50
  • I went ahead and edited it anyway to make it more clear what was what in terms of the explanation of the mapping and the usage. – nullromo Jan 16 '23 at 22:02
  • 1
    It's copying the entire line, not the visual selection. – Dennis Feb 17 '23 at 03:31
  • 1
    @Dennis You know what, I only ever use visual line mode so I never even considered this XD. According to `:help w_c`, this command will only "execute {cmd} with [range] **lines** as standard input," with **lines** being the important part here. I'm not sure there's a way to get this method to work with sub-line granularity. I thought this warranted its own question, so [I posted it](https://vi.stackexchange.com/q/40198/25982). – nullromo Feb 17 '23 at 18:26
  • Based on that question I posted, I was able to come up with a better solution, so I edited this answer accordingly. – nullromo Feb 18 '23 at 00:09
1

There are lots of quirks with WSL terminal, but using cross Vim copy/paste is top annoyance in my book. Nothing I tried as of April 2018 worked for pasting into Vim or other areas (using normal saneness) so, let's try to bypass the issue, and others related like buffer, for now. This is not a direct WSL solution, rather a workaround using a better terminal + SSH until MS provides a fix.

Putty, or it's extended fork Kitty, offer a more robust terminal compared to WSL. We can connect to the WSL (or any of your other servers) using SSH via localhost, using a custom port, and get a fuller featured terminal, including almost all Vim capabilities for bi-directional, or native pasting, scroll, etc. [You may need to tweak Vim conf to trigger all capabilities].

Putty/Kitty require an SSH server available in WSL, on a custom localhost port. If you haven't set up a localhost SSH server on your WSL already, here's a quick overview of how:

Step 1) Open the Ubuntu WSL terminal, do a sudo su to auth as root, run vim /etc/ssh/sshd_config to open SSH server conf.

Step 2) Look for "Port" near the first handful of lines. It may be set to 22. We need to set a custom port for our WSL SSH that doesn't collide. Hit i to edit. Let's use port 9977 for example.

Step 3) If you're a dev, or otherwise don't need to bother with keys for your localhost WSL SSH, look for password authentication. You can set PasswordAuthentication yes. Else, keys and higher security, or public access through firewall(s) on WSL, are beyond the scope of this answer.

Step 4) When done editing, hit esc to exit edit mode, then save+quit the file :wq. Restart ssh service using service ssh restart. Leave WSL open at this point as a master console.

Step 5) Create a new Putty/Kitty session, connect to localhost, using your custom port (9977 in our example). Log in with your WSL credentials, sudo su if you require root. You should now have a much more robust shell available. Repeat or screen as many views as you need.

I know it's not a direct answer, but at least it's a solution for now :)

dhaupin
  • 413
  • 2
  • 4
  • 13
1

You could use xclip or win32yank.exe. For some reason sometimes in WSL1 my clip.exe and win32yank.exe seem to have some runtime error so I am using mainly local xclip with an xserver running. Modified from a few other examples including a neovim clipboard .vim

You could just use top section to add ctrl-c ctrl-x (no ctrl-v yet!) without affecting how vim works aready, or add bottom section to yank to windows clipboard but have delete work normally using vim buffer (so hitting x etc still works quickly and as expected)

set clipboard=unnamedplus
if system('uname -a | egrep [Mm]icrosoft') != ''
 let g:lastyank = 'y'
 if executable('win32yank.exe')
    let g:copy = 'win32yank.exe -i --crlf'
    let g:paste = 'win32yank.exe -o --lf'
 elseif exists('$DISPLAY') && executable('xclip')
    let g:copy = 'xclip -i -selection clipboard'
    let g:paste = 'xclip -o -selection clipboard'
 else
    let g:copy = 'clip.exe'
    let g:paste = 'powershell.exe Get-Clipboard'
 endif
 augroup myYank
    autocmd!
    autocmd TextYankPost * if v:event.operator == 'y' | call system(g:copy, @") | let g:lastyank='y' | else | let g:lastyank='' | endif
    "autocmd TextYankPost * if v:event.operator ==# 'y' | call system(g:copy, @") | endif
    "autocmd TextYankPost * call system(g:copy, @")
 augroup END
 function! Paste(mode)
    if g:lastyank == 'y'
     let @" = system(g:paste)
    endif
    return a:mode
 endfunction
 map <expr> p Paste('p')
 map <expr> P Paste('P')
 " map Ctrl-c and Ctrl-x as expected
 func! GetSelectedText()
    normal gv"xy
    let result = getreg("x")
    return result
 endfunc
 noremap <C-c> :call system(g:copy, GetSelectedText())<CR>
 noremap <C-x> :call system(g:copy, GetSelectedText())<CR>gvx
endif
MerryDan
  • 11
  • 2
  • Thanks for your post! Is there a way to let `yG` copy thing to vim clipboard, and `yG` copy things to Windows clipboard? – roachsinai Jun 14 '21 at 11:24
1

You can open wsl distribution from Windows Terminal, then press Ctrl +Shift + V.

Open Windows Terminal, then click in "down arrow" enter image description here

Open vim and go to Insert mode and press Ctrl + Shift + V

If you want, you can get content from the "+" register and then paste with < leader > p

 " Copy to clipboard
 vnoremap  <leader>y  "+y
 nnoremap  <leader>y  "+y

" " Paste from clipboard
 nnoremap <leader>p "+p
 vnoremap <leader>p "+p
Grisotto
  • 111
  • 3
1

Lots of suggestions for the copy but I couldn't get any working for paste. I just settled for this in my vimrc

nmap PP :r!powershell.exe -command "Get-Clipboard"<CR>