I used to use "+y
to copy text to system's clipboard, but it doesn't work in vim of Bash on Windows.

- 521
- 1
- 6
- 15
-
1You can't. Use GVim if you want clipboard support on Windows. – romainl Jun 11 '17 at 07:09
-
The `"*` register does the trick for vim in git bash. E.g. to copy the current line: `"*yy` (then ctrl-v into e.g. your web browser URL field). Or the other way around: (e.g. after copying e.g. a URL), paste it into your current vim file: `"*p`. – Ralph Dec 09 '21 at 21:36
-
1I don't understand how this question was closed. Of course `vim` is a software tool primarily used by programmers. Was it closed because this question was asked related to Windows? – Cornelius Roemer Aug 21 '22 at 15:03
11 Answers
Since neither "*y nor "+y (...) work, an alternative is the following:
Add this to your .vimrc
and create a file called ~/.vimbuffer
" copy (write) highlighted text to .vimbuffer
vmap <C-c> y:new ~/.vimbuffer<CR>VGp:x<CR> \| :!cat ~/.vimbuffer \| clip.exe <CR><CR>
" paste from buffer
map <C-v> :r ~/.vimbuffer<CR>
Higlight any text using visual or visual-block and press ctrl-c
.
Paste copied text outside your terminal using the usual method or
paste copied text to any vim pane using ctrl-v
in normal or visual mode.
Ctrl-c
yanks the selected text, overwrites ~/.vimbuffer
with the selected text, runs a UNIX command to pipe out the data from ~/.vimbuffer
to clip.exe.
Any further improvement (e.g.: making command silent) is much appreciated!
Edit: command can now copy strings with any length, not just whole lines. Old command:
vmap <C-c> :w! ~/.vimbuffer \| !cat ~/.vimbuffer \| clip.exe <CR><CR>
Edit2: @Tropilio below has a much cleaner approach down in the comments using system events. I've been using that for a year now.

- 638
- 6
- 12
-
For some reason, it does not work for me. It inserts two chars `:|` ( colon and pipe chars) at the very beginning of the selection and it does not copy the contents to windows clipboard. When there is contents in `.vimbuffer`, and I enter `:!cat ~/.vimbuffer \| clip.exe
` into vim, I get the following error: `cat: '|' : no such file or directory` and `cat: clip.exe: No such file or directory` – user1135541 Dec 19 '17 at 14:14 -
This might be because you're using the command from inside vim. If you simply want to copy the content of `~/.vimbuffer` to clipboard, use `:!cat ~/.vimbuffer | clip.exe
` - you don't have to escape the | char (with a \) from vim, only in `.vimrc`. Let me know if it still not working. – davidanderle Dec 20 '17 at 14:35 -
2I can confirm this works on the latest WSL on Windows 10. Microsoft Windows [Version 10.0.17134.286] – Padge Sep 20 '18 at 17:55
-
Thanks, this works! But for some reason, whenever I use the `
` command, there's a glitch where the screen flickers a couple of times... – Tropilio Mar 19 '20 at 10:28 -
@Tropilio Yes, unfortunately that happens for me, too. I think the flicker happens because of the repeated "bang!"s. I was trying to make the script work by using vim's syscall (vim not having to be suspended), but the piping failed. – davidanderle Apr 21 '20 at 09:24
-
8I am now using a different approach, maybe it can be useful to you as well. I use an autocommand that gets automatically triggered everytime I yank some text: `autocmd TextYankPost * call system('echo '.shellescape(join(v:event.regcontents, "\
")).' | clip.exe')` This doesn't cause any flicker or lag. – Tropilio Apr 21 '20 at 09:31 -
@Tropilio Wow, TextYankPost is a great idea! This works really well with my other hack: `noremap
– davidanderle Apr 21 '20 at 11:06:let @9 = trim(system("paste.exe")) \| normal "9p ` For this you need [paste.cs](https://github.com/davidanderle/dotfiles/blob/master/paste.cs) (or something similar) compiled to paste.exe and placed in your System32 directoly (where clip.exe lives).
To copy to the clipboard from within vim in Bash on Windows 10, hold Shift
and drag the cursor over text. then press enter
A selection should look like this before pressing enter
:
EDIT: This only works with text that fits on the screen all at once; it cannot be used to copy blocks of text that span many 'screens'

- 6,242
- 7
- 41
- 65
-
2This copies the text from the console though and not in vim per se. – Ignacio Vazquez-Abrams Jun 11 '17 at 06:18
-
Correct, but I do not know of a way that doesn't. (If you want to use the stock vim that comes bundled with WSL) – ifconfig Jun 11 '17 at 06:20
-
1vim help on my (non-Windows) system claims that `"*` is the correct register to use. – Ignacio Vazquez-Abrams Jun 11 '17 at 06:25
-
1Right, but it requires vim to be installed in a different way, `vim-gnome` instead of just `vim` – ifconfig Jun 11 '17 at 06:26
-
*shrug* I suppose they decided that vim running under WSL didn't need to actually integrate with Windows at all. – Ignacio Vazquez-Abrams Jun 11 '17 at 06:27
So there's a lot of answers, even on cross-network questions like this one on Super User, and this one on Vi and Vim, and unfortunately I'm not satisfied with any of them, so here's a different answer.
Neovim
If we're using Neovim, it's easy. We can follow their FAQ under How to use the Windows clipboard from WSL. The rest of this section is just context.
By setting set clipboard=unnamedplus
as if we were on a regular Linux system under X11, we tell Neovim to use the system registers as our default clipboard when yanking and pasting. Based on where Neovim is running, it chooses an appropriate provider to interact with these system registers. For v0.4.3, how that provider is chosen can be found at provider#clipboard#Executable.
While this solution requires installing an external binary win32yank.exe
, I'm personally very satisfied with it as both clip.exe
and powershell.exe [Set|Get]-Clipboard
pale in user experience to it. For example, clip.exe
only supports copying, but fails to address the pasting issue. And while the Powershell Get-Clipboard
cmdlet allows for us to paste into Vim from our Windows clipboard, it'll retain Windows line-endings, so there will be nasty ^M
s everywhere after pasting. In addition, it's a super small binary and only has to be installed within our WSL distro; nothing on the Windows side.
curl -sLo /tmp/win32yank.zip https://github.com/equalsraf/win32yank/releases/download/v0.0.4/win32yank-x64.zip
unzip -p /tmp/win32yank.zip win32yank.exe > /tmp/win32yank.exe
chmod +x /tmp/win32yank.exe
sudo mv /tmp/win32yank.exe /usr/local/bin/
Vim
If we're just using regular Vim, we can still use win32yank.exe
, but we have to manually implement what Neovim would normally do for us. That is, the following:
set clipboard=unnamed
autocmd TextYankPost * call system('win32yank.exe -i --crlf', @")
function! Paste(mode)
let @" = system('win32yank.exe -o --lf')
return a:mode
endfunction
map <expr> p Paste('p')
map <expr> P Paste('P')
First set the clipboard to the default register (@"
) as the system registers might not even be enabled if Vim was compiled without clipboard support like on my default Ubuntu WSL distro. Copies use an autocmd to pass the default register to win32yank
, and pastes intercept the paste to assign the system clipboard to the default register.
This works but it's noticeably jittery if performing several successive yanks and pastes quickly as we have to shell out every time. We can improve the yank by debouncing it:
autocmd TextYankPost * call YankDebounced()
function! Yank(timer)
call system('win32yank.exe -i --crlf', @")
redraw!
endfunction
let g:yank_debounce_time_ms = 500
let g:yank_debounce_timer_id = -1
function! YankDebounced()
let l:now = localtime()
call timer_stop(g:yank_debounce_timer_id)
let g:yank_debounce_timer_id = timer_start(g:yank_debounce_time_ms, 'Yank')
endfunction
But this will require Vim 8, and if you have to upgrade, I'd recommend to just go with Neovim instead. Trying to implement proper caching and debouncing would be a headache!

- 1,243
- 1
- 16
- 26

- 635
- 8
- 14
-
2Works even for WSL2. This is the best and most simple answer atleast for neovim users. – Siddharth Pant Jun 04 '20 at 16:09
-
1`mv /tmp/win32yank.exe ~/bin` renames the .exe to `bin` and places it in `~`. Are you sure you don't mean `mv /tmp/win32yank.exe /usr/local/bin/win32yank.exe` (for Ubuntu)? – run_the_race Jul 08 '20 at 18:28
-
I can confirm it works on WSL2 *but*, you need to be aware: 1. you should specifically configure `neovim` to use `win32yank.exe`. The issue being that if you have now (or later install) any of the other options with a higher priority (`xclip`, etc.) then they will take precedence and your clipboard will not work/stop working. 2. `neovim` may start lagging (up to 5 seconds) when doing things like cut/delete. This is likely due to the communication between Win and the Linux (hyper-v) VM. – AntonOfTheWoods Jul 14 '20 at 03:56
-
The `Vim` section worked for me using `vim-nox`. This was the fourth solution I tried. (I haven't bothered with the debounce yet) – Matt Parrilla Mar 11 '21 at 22:00
-
Note that it is the `p`/`P` commands that read the clipboard contents into the register. This means you can't access the register directly _before_ using either of those two commands. In particular, `i
"` does not work immediately. This also changes the behaviour of `xp` to be in-place. – mkjeldsen Jun 25 '21 at 08:19 -
I have *"WSL Debian"* with the `win32yank.exe` successfully installed. I can call it like `win32yank.exe --help` and get a response. But then I add `set clipboard=unnamedplus` in the `~/.config/nvim/init.vim` and nothing works inside the Neovim. Why would that be? @AntonOfTheWoods I made sure to uninstall `xclip` and `xset`. – 71GA Apr 05 '22 at 11:22
-
1@71GA have a look at my answer on SuperUser https://superuser.com/questions/1291425/windows-subsystem-linux-make-vim-use-the-clipboard/1557751#1557751. Maybe also try putting in the full unix path to win32yank.exe if the copy isn't working. – AntonOfTheWoods Apr 18 '22 at 05:20
-
I settled for another better solution. I use X server on windows now, and do everything inside WSL as I did in Linux. – 71GA Apr 19 '22 at 08:16
If you only care about copying complete lines, you can use Vim's ability to pipe the file contents to an external program. So you can do
:w !clip.exe
to pipe into clip.exe
. If you need specific lines, say 2 through 10, you can just do
:2,10w !clip.exe

- 198
- 2
- 7
If you don't want to set up an X server, this method will allow you to copy selected text to your clipboard using the clip.exe
program which comes shipped with Windows.
The code snippets below can be placed in your .vimrc
file.
First create a helper function which will return the currently selected text as a string. We can use this function to pipe highlighted text into clip.exe
:
func! GetSelectedText()
normal gv"xy
let result = getreg("x")
return result
endfunc
The system
function will allow us to call native programs and pipe parameters into them. The snippet below sets up two key mappings; the first line will allow Ctrl+C to be used for copying text and the second will allow Ctrl+X for cutting text:
noremap <C-C> :call system('clip.exe', GetSelectedText())<CR>
noremap <C-X> :call system('clip.exe', GetSelectedText())<CR>gvx
After saving the changes to your .vimrc
file you should be good to go.
If you are going to be using your .vimrc
on multiple systems, I suggest wrapping these mappings in an if
statement to check if clip.exe
actually exists:
if !has("clipboard") && executable("clip.exe")
noremap <C-C> :call system('clip.exe', GetSelectedText())<CR>
noremap <C-X> :call system('clip.exe', GetSelectedText())<CR>gvx
endif
The above will also allow Vim to ignore those key bindings if it has direct access to the system clipboard.
You might also want to add keybindings for when vim does have access to the clipboard, like so:
if has("clipboard")
vnoremap <C-X> "+x
vnoremap <S-Del> "+x
vnoremap <C-C> "+y
vnoremap <C-Insert> "+y
map <C-V> "+gP
map <S-Insert> "+gP
cmap <C-V> <C-R>+
cmap <S-Insert> <C-R>+
endif
Which will come in handy if you are using Vim natively on Windows or are using vim-gtk
on a Linux system.

- 350
- 1
- 7
- 15
-
1Better solution than accepted imo due to no need for a buffer file. Thanks for sharing this! – rococo Jun 10 '19 at 17:49
Add following to .vimrc
:
autocmd TextYankPost * if v:event.operator ==# 'y' | call system('/mnt/c/Windows/System32/clip.exe', @0) | endif
For convenience, if desired, you can add copying by ctrl + c
vmap <C-c> y

- 2,510
- 3
- 22
- 35
If you want use vim that bundled within WSL, you can only use the Clipboard provided by vim itself, which means you can only copy & paste within vim only.
Or, you can try:
- Install VcXsrv and run it.
export DISPLAY=localhost:0
in your WSL Bash.- Run vim-gtk or vim-gnome(or any other GUI Apps) and try Clipboard across Linux and Windows.

- 2,063
- 13
- 12
-
According to a WSL GitHub-Issue, this should work. See also here: https://github.com/Microsoft/WSL/issues/892#issuecomment-275873108 – dwettstein Mar 11 '18 at 13:12
Combining the information above, it's possible to copy simple text from any register to a clipboard without using any keybinding (what can be more convenient in some cases). For example, if you want to copy last yanked text to the windows clipboard, enter the following command (start typing):
:call system('clip.exe', '
Now press Ctrl+r, followed by a register +. It will paste a text from the specified register. Next, close the single quote and the parentheses. The command will look like:
:call system('clip.exe', 'a text from 0 register')
Press Enter, done!

- 988
- 12
- 23
Below are mappings
- in normal mode
cy
,cyy
andcY
(=Clipboard Yank) that copy, respectively, the given text object, line(s), rest of the line from the cursor position to the clipboard, and - in visual mode
Y
that copies the visual selection to the clipboard,
independent of whether Vim is started in WSL or not.
nnoremap cy "+y
nnoremap <sid>(mgu) m`_
onoremap <sid>(gu) g_
nnoremap <sid>(ggg) g``
nmap <expr> cyy '<sid>(mgu)cy' . v:count1 . '<sid>(gu)' . '<sid>(ggg)'
nmap cY cy<sid>(gu)
xnoremap Y "+y
if has('unix') && executable('clip.exe')
" From :help map-operator
function! SendToClip(type, ...) abort
if a:0
" Visual mode
normal! gv"+y
elseif a:type ==# 'line'
normal! '[V']"+y
elseif a:type ==# 'char'
normal! `[v`]"+y
endif
call system('clip.exe', @+)
endfunction
nnoremap <silent> cy :set operatorfunc=SendToClip<cr>g@
xnoremap <silent> Y :<C-U>call SendToClip(visualmode(),1)<cr>
endif

- 238
- 2
- 6
vmap <silent> <leader>y :w !clip.exe<CR><CR>
"---------------------- :w !clip.exe
" The core command, thanks to Mitchell's answer.
"---------------------------------- <CR><CR>
" The first <CR> closes the command;
" the second <CR> suppresses "Press ENTER or type command to continue".
"--- :h map-silent
" This fix the flicker caused by external commands and <CR><CR>.
"------------ :h leader
" `:echo mapleader` to view your leader key.
Standing on the shoulders of giants, I'm using the above solution now.

- 1,531
- 1
- 20
- 27
What works for me is simply:
Holding Shift key and selecting the text you would like to copy using the mouse. Then go to any text editor on your host and paste; your selected text should be there.

- 14,913
- 17
- 70
- 99