How to paste over without overwriting register

VimVi

Vim Problem Overview


Does anyone know of a way to paste over a visually selected area without having the selection placed in the default register?

I know I can solve the problem by always pasting from an explicit register. But it's a pain in the neck to type "xp instead of just p

Vim Solutions


Solution 1 - Vim

Use the following:

xnoremap p pgvy

this will reselect and re-yank any text that is pasted in visual mode.

Edit: in order this to work with "xp you can do:

xnoremap p pgv"@=v:register.'y'<cr>

v:register expands to the last register name used in a normal mode command.

Solution 2 - Vim

I don't like the default vim behavior of copying all text deleted with d, D, c, or C into the default register.

I've gotten around it by mapping d to "_d, c to "_c, and so on.

From my .vimrc:

"These are to cancel the default behavior of d, D, c, C
"  to put the text they delete in the default register.
"  Note that this means e.g. "ad won't copy the text into
"  register a anymore.  You have to explicitly yank it.
nnoremap d "_d
vnoremap d "_d
nnoremap D "_D
vnoremap D "_D
nnoremap c "_c
vnoremap c "_c
nnoremap C "_C
vnoremap C "_C

Solution 3 - Vim

"{register}p won't work as you describe. It will replace the selection with the content of the register. You will have instead to do something like:

" I haven't found how to hide this function (yet)
function! RestoreRegister()
  let @" = s:restore_reg
  return ''
endfunction

function! s:Repl()
    let s:restore_reg = @"
    return "p@=RestoreRegister()\<cr>"
endfunction

" NB: this supports "rp that replaces the selection by the contents of @r
vnoremap <silent> <expr> p <sid>Repl()

Which should be fine as long as you don't use a plugin that has a non-nore vmap to p, and that expects a register to be overwritten.

This code is available as a script there. Ingo Karkat also defined a plugin solving the same issue.

Solution 4 - Vim

In your .vimrc

xnoremap p "_dP

I found this from a response on a similar thread, but the original source was http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text. It mentions some drawbacks, however it works fine for me.

Solution 5 - Vim

Luc Hermitte's solution works like a charm. I was using it for about a week or so. Then I discovered a solution from Steve Losh's .vimrc that works nicely if YankRing is part of your plugin/bundle lineup:

function! YRRunAfterMaps()                                                                                                      
    " From Steve Losh, Preserve the yank post selection/put.    
    vnoremap p :<c-u>YRPaste 'p', 'v'<cr>gv:YRYankRange 'v'<cr> 
endfunction  

                                               

Solution 6 - Vim

Try this in your ~/.vimrc:

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremap means that this is only for Visual mode, not Visual + Select modes.

  • <expr> means that {rhs} of the xnoremap {lhs} {rhs} setting is evaluated as an expression.

  • In this case, our expression of 'pgv"'.v:register.'y' is using . for concatenation.

  • v:register is evaluated to the register being used during the fulfillment of the mapping.

The result of "xp would evaluate to pgv"xy, where x is the register.

I was helped by an answer to this stackoverflow question: Vim - mapping with an optional register prefix in conjunction with Benoit's answer on this page

Solution 7 - Vim

Luc's function worked well for me after I made a change to support the fact that I have clipboard=unnamed set:

function! RestoreRegister()
    let @" = s:restore_reg
    if &clipboard == "unnamed"
        let @* = s:restore_reg
    endif
    return ''
endfunction

Solution 8 - Vim

Luc Hermitte's did the trick! Really good. Here's his solution put in a toggle function, so you can switch between normal behavior and no-replace-register put.

the command ,u toggles the behavior

let s:putSwap = 1 
function TogglePutSwap()
    if s:putSwap
        vnoremap <silent> <expr> p <sid>Repl()
        let s:putSwap = 0 
        echo 'noreplace put'
    else
        vnoremap <silent> <expr> p p 
        let s:putSwap = 1 
        echo 'replace put'
    endif
    return
endfunction
noremap ,p :call TogglePutSwap()<cr>

Solution 9 - Vim

duct-tape programming, but works for me:

nmap viwp viwpyiw
nmap vi'p vi'pyi'
nmap vi"p vi"pyi"
nmap vi(p vi(pyi(
nmap vi[p vi[pyi[nmap vi<p vi<pyi<

Solution 10 - Vim

try -

:set guioptions-=a
:set guioptions-=A

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStarr HorneView Question on Stackoverflow
Solution 1 - VimBenoitView Answer on Stackoverflow
Solution 2 - VimJeff LakeView Answer on Stackoverflow
Solution 3 - VimLuc HermitteView Answer on Stackoverflow
Solution 4 - VimJason DenneyView Answer on Stackoverflow
Solution 5 - VimTaineView Answer on Stackoverflow
Solution 6 - VimmrakView Answer on Stackoverflow
Solution 7 - VimdanpriceView Answer on Stackoverflow
Solution 8 - VimJoernsnView Answer on Stackoverflow
Solution 9 - Vimsteven_nobleView Answer on Stackoverflow
Solution 10 - VimGowriView Answer on Stackoverflow