diff options
-rw-r--r-- | runtime/autoload/provider/clipboard.vim | 215 | ||||
-rw-r--r-- | runtime/doc/news.txt | 2 | ||||
-rw-r--r-- | runtime/doc/provider.txt | 21 |
3 files changed, 167 insertions, 71 deletions
diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim index 7e7feb50e0..32d8841b72 100644 --- a/runtime/autoload/provider/clipboard.vim +++ b/runtime/autoload/provider/clipboard.vim @@ -67,6 +67,113 @@ function! s:set_osc52() abort return 'OSC 52' endfunction +function! s:set_pbcopy() abort + let s:copy['+'] = ['pbcopy'] + let s:paste['+'] = ['pbpaste'] + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + let s:cache_enabled = 0 + return 'pbcopy' +endfunction + +function! s:set_wayland() abort + let s:copy['+'] = ['wl-copy', '--type', 'text/plain'] + let s:paste['+'] = ['wl-paste', '--no-newline'] + let s:copy['*'] = ['wl-copy', '--primary', '--type', 'text/plain'] + let s:paste['*'] = ['wl-paste', '--no-newline', '--primary'] + return 'wl-copy' +endfunction + +function! s:set_wayclip() abort + let s:copy['+'] = ['waycopy', '-t', 'text/plain'] + let s:paste['+'] = ['waypaste', '-t', 'text/plain'] + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'wayclip' +endfunction + +function! s:set_xsel() abort + let s:copy['+'] = ['xsel', '--nodetach', '-i', '-b'] + let s:paste['+'] = ['xsel', '-o', '-b'] + let s:copy['*'] = ['xsel', '--nodetach', '-i', '-p'] + let s:paste['*'] = ['xsel', '-o', '-p'] + return 'xsel' +endfunction + +function! s:set_xclip() abort + let s:copy['+'] = ['xclip', '-quiet', '-i', '-selection', 'clipboard'] + let s:paste['+'] = ['xclip', '-o', '-selection', 'clipboard'] + let s:copy['*'] = ['xclip', '-quiet', '-i', '-selection', 'primary'] + let s:paste['*'] = ['xclip', '-o', '-selection', 'primary'] + return 'xclip' +endfunction + +function! s:set_lemonade() abort + let s:copy['+'] = ['lemonade', 'copy'] + let s:paste['+'] = ['lemonade', 'paste'] + let s:copy['*'] = ['lemonade', 'copy'] + let s:paste['*'] = ['lemonade', 'paste'] + return 'lemonade' +endfunction + +function! s:set_doitclient() abort + let s:copy['+'] = ['doitclient', 'wclip'] + let s:paste['+'] = ['doitclient', 'wclip', '-r'] + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'doitclient' +endfunction + +function! s:set_win32yank() abort + if has('wsl') && getftype(exepath('win32yank.exe')) == 'link' + let win32yank = resolve(exepath('win32yank.exe')) + else + let win32yank = 'win32yank.exe' + endif + let s:copy['+'] = [win32yank, '-i', '--crlf'] + let s:paste['+'] = [win32yank, '-o', '--lf'] + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'win32yank' +endfunction + +function! s:set_putclip() abort + let s:copy['+'] = ['putclip'] + let s:paste['+'] = ['getclip'] + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'putclip' +endfunction + +function! s:set_clip() abort + let s:copy['+'] = ['clip'] + let s:paste['+'] = ['powershell', '-NoProfile', '-NoLogo', '-Command', 'Get-Clipboard'] + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'clip' +endfunction + +function! s:set_termux() abort + let s:copy['+'] = ['termux-clipboard-set'] + let s:paste['+'] = ['termux-clipboard-get'] + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'termux-clipboard' +endfunction + +function! s:set_tmux() abort + let tmux_v = v:lua.vim.version.parse(system(['tmux', '-V'])) + if !empty(tmux_v) && !v:lua.vim.version.lt(tmux_v, [3,2,0]) + let s:copy['+'] = ['tmux', 'load-buffer', '-w', '-'] + else + let s:copy['+'] = ['tmux', 'load-buffer', '-'] + endif + let s:paste['+'] = ['tmux', 'save-buffer', '-'] + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'tmux' +endfunction + let s:cache_enabled = 1 let s:err = '' @@ -78,9 +185,34 @@ function! provider#clipboard#Executable() abort " Setting g:clipboard to v:false explicitly opts-in to using the "builtin" clipboard providers below if exists('g:clipboard') && g:clipboard isnot# v:false if v:t_string ==# type(g:clipboard) + " Handle string form of g:clipboard for all builtin providers if 'osc52' == g:clipboard " User opted-in to OSC 52 by manually setting g:clipboard. return s:set_osc52() + elseif 'pbcopy' == g:clipboard + return s:set_pbcopy() + elseif 'wl-copy' == g:clipboard + return s:set_wayland() + elseif 'wayclip' == g:clipboard + return s:set_wayclip() + elseif 'xsel' == g:clipboard + return s:set_xsel() + elseif 'xclip' == g:clipboard + return s:set_xclip() + elseif 'lemonade' == g:clipboard + return s:set_lemonade() + elseif 'doitclient' == g:clipboard + return s:set_doitclient() + elseif 'win32yank' == g:clipboard + return s:set_win32yank() + elseif 'putclip' == g:clipboard + return s:set_putclip() + elseif 'clip' == g:clipboard + return s:set_clip() + elseif 'termux' == g:clipboard + return s:set_termux() + elseif 'tmux' == g:clipboard + return s:set_tmux() endif endif @@ -102,88 +234,29 @@ function! provider#clipboard#Executable() abort let s:cache_enabled = get(g:clipboard, 'cache_enabled', 0) return get(g:clipboard, 'name', 'g:clipboard') elseif has('mac') - let s:copy['+'] = ['pbcopy'] - let s:paste['+'] = ['pbpaste'] - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - let s:cache_enabled = 0 - return 'pbcopy' + return s:set_pbcopy() elseif !empty($WAYLAND_DISPLAY) && executable('wl-copy') && executable('wl-paste') - let s:copy['+'] = ['wl-copy', '--type', 'text/plain'] - let s:paste['+'] = ['wl-paste', '--no-newline'] - let s:copy['*'] = ['wl-copy', '--primary', '--type', 'text/plain'] - let s:paste['*'] = ['wl-paste', '--no-newline', '--primary'] - return 'wl-copy' + return s:set_wayland() elseif !empty($WAYLAND_DISPLAY) && executable('waycopy') && executable('waypaste') - let s:copy['+'] = ['waycopy', '-t', 'text/plain'] - let s:paste['+'] = ['waypaste', '-t', 'text/plain'] - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - return 'wayclip' + return s:set_wayclip() elseif !empty($DISPLAY) && executable('xsel') && s:cmd_ok('xsel -o -b') - let s:copy['+'] = ['xsel', '--nodetach', '-i', '-b'] - let s:paste['+'] = ['xsel', '-o', '-b'] - let s:copy['*'] = ['xsel', '--nodetach', '-i', '-p'] - let s:paste['*'] = ['xsel', '-o', '-p'] - return 'xsel' + return s:set_xsel() elseif !empty($DISPLAY) && executable('xclip') - let s:copy['+'] = ['xclip', '-quiet', '-i', '-selection', 'clipboard'] - let s:paste['+'] = ['xclip', '-o', '-selection', 'clipboard'] - let s:copy['*'] = ['xclip', '-quiet', '-i', '-selection', 'primary'] - let s:paste['*'] = ['xclip', '-o', '-selection', 'primary'] - return 'xclip' + return s:set_xclip() elseif executable('lemonade') - let s:copy['+'] = ['lemonade', 'copy'] - let s:paste['+'] = ['lemonade', 'paste'] - let s:copy['*'] = ['lemonade', 'copy'] - let s:paste['*'] = ['lemonade', 'paste'] - return 'lemonade' + return s:set_lemonade() elseif executable('doitclient') - let s:copy['+'] = ['doitclient', 'wclip'] - let s:paste['+'] = ['doitclient', 'wclip', '-r'] - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - return 'doitclient' + return s:set_doitclient() elseif executable('win32yank.exe') - if has('wsl') && getftype(exepath('win32yank.exe')) == 'link' - let win32yank = resolve(exepath('win32yank.exe')) - else - let win32yank = 'win32yank.exe' - endif - let s:copy['+'] = [win32yank, '-i', '--crlf'] - let s:paste['+'] = [win32yank, '-o', '--lf'] - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - return 'win32yank' + return s:set_win32yank() elseif executable('putclip') && executable('getclip') - let s:copy['+'] = ['putclip'] - let s:paste['+'] = ['getclip'] - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - return 'putclip' + return s:set_putclip() elseif executable('clip') && executable('powershell') - let s:copy['+'] = ['clip'] - let s:paste['+'] = ['powershell', '-NoProfile', '-NoLogo', '-Command', 'Get-Clipboard'] - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - return 'clip' + return s:set_clip() elseif executable('termux-clipboard-set') - let s:copy['+'] = ['termux-clipboard-set'] - let s:paste['+'] = ['termux-clipboard-get'] - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - return 'termux-clipboard' + return s:set_termux() elseif executable('tmux') && (!empty($TMUX) || 0 == jobwait([jobstart(['tmux', 'list-buffers'])], 2000)[0]) - let tmux_v = v:lua.vim.version.parse(system(['tmux', '-V'])) - if !empty(tmux_v) && !v:lua.vim.version.lt(tmux_v, [3,2,0]) - let s:copy['+'] = ['tmux', 'load-buffer', '-w', '-'] - else - let s:copy['+'] = ['tmux', 'load-buffer', '-'] - endif - let s:paste['+'] = ['tmux', 'save-buffer', '-'] - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - return 'tmux' + return s:set_tmux() elseif get(get(g:, 'termfeatures', {}), 'osc52') && &clipboard ==# '' " Don't use OSC 52 when 'clipboard' is set. It can be slow and cause a lot " of user prompts. Users can opt-in to it by setting g:clipboard manually. diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index eee39f81f5..72ab3373f7 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -138,6 +138,8 @@ OPTIONS • 'winborder' add bold style. +• |g:clipboard| accepts a string name to force any builtin clipboard tool. + PERFORMANCE • todo diff --git a/runtime/doc/provider.txt b/runtime/doc/provider.txt index 7a4cc0ee7d..4f7807f721 100644 --- a/runtime/doc/provider.txt +++ b/runtime/doc/provider.txt @@ -240,6 +240,27 @@ The "copy" function stores a list of lines and the register type. The "paste" function returns the clipboard as a `[lines, regtype]` list, where `lines` is a list of lines and `regtype` is a register type conforming to |setreg()|. +Nvim also supports setting g:clipboard to a string to use a builtin clipboard provider: + + - "tmux" - Use tmux clipboard + - "xclip" - Use xclip for X11 clipboard + - "xsel" - Use xsel for X11 clipboard + - "wl-copy" - Use Wayland clipboard with wl-copy/wl-paste + - "wayclip" - Use Wayland clipboard with waycopy/waypaste + - "lemonade" - Use lemonade clipboard (for SSH) + - "doitclient" - Use doitclient clipboard (for SSH) + - "win32yank" - Use win32yank clipboard (for Windows) + - "clip" - Use clip/powershell clipboard (for Windows) + - "putclip" - Use putclip/getclip clipboard (for Windows/Cygwin) + - "termux" - Use Termux clipboard + - "pbcopy" - Use macOS clipboard + - "osc52" - Use OSC 52 sequence + +Example: >vim + let g:clipboard = 'tmux' + +This is equivalent to using the full dictionary configuration for tmux shown above. + *clipboard-wsl* For Windows WSL, try this g:clipboard definition: >vim |