blog · git · desktop · images · contact & privacy · gopher


Integrating Vim and xclip

2020-06-18

gVim has special registers, "* and "+, that correspond to X11’s PRIMARY and CLIPBOARD selections. I suspect that most people use those (or just the mouse). As usual with X11 selections, they are lost when the application quits. One option to deal with this is to run a clipboard manager.

Another option is to explicitly fork a new process that sticks around and holds the selection. That’s what xclip does, essentially. Another advantage is that it works with a “normal” Vim, so no gVim needed.

I have these key bindings in my ~/.vimrc:

nmap <Leader>xc :call X11Copy()<CR>
vmap <Leader>xc "xy:call X11CopyRegister('x')<CR>
nmap <Leader>xp :call X11PasteClipboard()<CR>
nmap <Leader>xP :call X11PastePrimary()<CR>

When text is selected in visual mode, I can hit ,xc to copy it to X11’s CLIPBOARD. Pressing ,xc without a selection copies the entire file. ,xp is for pasting.

The functions then look like this:

fun! X11Copy()
    silent %w !setsid xclip -selection clipboard
endfun

fun! X11CopyRegister(reg)
    let l:ignore = system('setsid xclip -selection clipboard', getreg(a:reg))
endfun

fun! X11PasteClipboard()
    r !xclip -selection clipboard -o
endfun

fun! X11PastePrimary()
    r !xclip -o
endfun

setsid creates a new session, but more importantly a new process group, so my xclip won’t get killed by a SIGHUP when the terminal is closed unexpectedly.

It took me a while to figure out the correct way for “copy text from visual mode”. It’s a bit tricky, because I want to copy exactly what has been selected. The workaround consists of first copying to register "x and then writing the contents of that register to xclip. (Naïve approaches quickly lead you to :'<,'>, which operates on lines.)

,xc and ,xp are personal preference. I like that it is very distinct from the usual register key bindings. Makes you aware that, yes, now you’re dealing with an X11 selection.

Comments?