15

While using WSL/Bash for Windows I want to be able to use y yy 3y and p the same way they always work in vim, but connecting to the system clipboard shared by all apps, not to vim's internal clipboard... I already have ditto to manage clipboard history.

It seems that Vim already has a built in option to synchronize the copy/paste buffer with the system clipboard... Yet the problem when running WSL is that you actually need to use /mnt/c/Windows/System32/clip.exe to access the clipboard... So even though I would like to be able to use:

set clipboard^=unnamed

It doesn't seem to have WSL support yet.

I understand the neovim does have this as an option, but I don't really want to experiment with neovim right now...

For now, the closest thing to a workaround that I've found is:

nnoremap <silent> <leader>y :call system('/mnt/c/Windows/System32/clip.exe', @0)<CR>
vnoremap <silent> <leader>y :call system('/mnt/c/Windows/System32/clip.exe', @0)<CR>

But this is a really horrible solution in my opinion... It makes copying a two-steps process...

Of course I can do some copy and paste with the mouse/shift+ins, yet I think there must be a way to get this synchronization to work properly in Vim.

Vivian De Smedt
  • 16,336
  • 3
  • 18
  • 37
erwin
  • 281
  • 3
  • 9

3 Answers3

13

I'm aware this is a very old question but I recently found a good solution. After much frustration, I came across these ways to access the windows system clipboard by copying and pasting.

By copying, with vim version >= 8.0.1394, as noted in another answer https://vi.stackexchange.com/a/15190

let s:clip = '/mnt/c/Windows/System32/clip.exe' 
if executable(s:clip)
    augroup WSLYank
        autocmd!
        autocmd TextYankPost * call system('echo '.shellescape(join(v:event.regcontents, "\<CR>")).' | '.s:clip)
    augroup END
end

Pasting, mapping to fake registry commands, i.e. "=p or "+p or whatever.

map <silent> "=p :r !powershell.exe -Command Get-Clipboard<CR>
map! <silent> <C-r>= :r !powershell.exe -Command Get-Clipboard<CR>

" I thought this will be better :)
noremap "+p :exe 'norm a'.system('/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -Command Get-Clipboard')<CR>

Right-click pasting works, but is unsatisfying if you don't want to use the mouse

questionmark
  • 141
  • 1
  • 6
  • On WSL vi I have added nnoremap <S-Insert> :r !powershell.exe -Command "& {Get-Clipboard}"<Enter> – Walter A Jan 30 '20 at 23:15
  • Thanks for the helpful answer! I was wondering if it would be possible to also use a fake register for the yank command. Something like noremap "+y :exe 'norm a'.system('echo '.shellescape(join(v:event.regcontents, "\<CR>")).' | clip.exe')<CR> (which doesn't work...) – Tropilio Apr 21 '20 at 08:41
6

What about this?

if system('uname -r') =~ "Microsoft"
  augroup Yank
    autocmd!
    autocmd TextYankPost * :call system('clip.exe ',@")
  augroup END
endif

uname is a Linux terminal command which returns OS info, such that it will return Linux for WSL. Whereas with -r flag, the command returns release info of OS, thus it should include "Windows".

TextYankPost is a vim event (see :h TextYankPost in vim), which detect your text yank activity.

clip.exe is a Windows command prompt's command in WSL (see CLIP /? in command prompt) which copy text or return from a command into clipbord via text | clip.exe or command | clip.exe. Here the clip.exe is executed from vim by vim function system.

aohmusi
  • 59
  • 1
  • 2
2

I've made a PR for WSL support to fakeclip some time ago.

See vimawesome on how to install it; help fakeclip for usage.

laktak
  • 2,933
  • 13
  • 27