How to “copy to clipboard” in vim of Bash on Windows?

前端 未结 9 1009
执念已碎
执念已碎 2020-12-13 00:38

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

相关标签:
9条回答
  • 2020-12-13 01:14

    Below are mappings

    • in normal mode cy, cyy and cY (=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
    
    0 讨论(0)
  • 2020-12-13 01:16

    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'

    0 讨论(0)
  • 2020-12-13 01:22

    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.

    0 讨论(0)
  • 2020-12-13 01:23

    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
    

    See Piping buffer to external command in Vim

    0 讨论(0)
  • 2020-12-13 01:24

    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>

    0 讨论(0)
  • 2020-12-13 01:29

    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!

    0 讨论(0)
提交回复
热议问题