Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

So I usually find myself copying text from one point to another while overwriting old text where the new is pasted:

blah1
newtext
blah2
wrong1
blah3
wrong2
blah4

Suppose I visual-mark newtext and yank it. Now I select wrong1 (which could be anything, not necessarily just a word) and paste the newtext. However, if I now do the same with wrong2 it will be replaced with wrong1 instead of newtext.

So how do I keep the text that is in the buffer from being swapped with the text that I am currently overwriting?

Edit 1

Although I quite like the reigister suggestions (I think I will start using registers more, now that I discovered the :dis command), I am going with a modification of jinfield's answer, because I do not use the swapping mode.

vnoremap p "0p
vnoremap P "0P
vnoremap y "0y
vnoremap d "0d

does the trick perfectly.

Edit 2

I was too fast; romainl's solution is precisely what I was looking for, without the hack in Edit 1.
Actually, vnoremap p "_dP is enough!
So, changing accepted answer.

share|improve this question
2  
Hey fyi, I've long used that vnoremap p "_dP map, and I've noticed that it doesn't work well for the last word/character in a line. I've gone back to the vnoremap p "0p, vnoremap P "0P, and set clipboard=unnamed (for OSX) – Kache Aug 1 '14 at 6:40
up vote 12 down vote accepted

I have these mappings in my .vimrc:

" delete without yanking
nnoremap <leader>d "_d
vnoremap <leader>d "_d

" replace currently selected text with default register
" without yanking it
vnoremap <leader>p "_dP

"_ is the "blackhole register", according to :help "_:

"When writing to this register, nothing happens. This can be used to delete text without affecting the normal registers. When reading from this register, nothing is returned. {not in Vi}"

share|improve this answer
1  
I've used that vnoremap p "_dP map and noticed that it doesn't work well for the last word/character in a line. I've gone back to the vnoremap p "0p, vnoremap P "0P, and set clipboard=unnamed (for OSX) – Kache Aug 1 '14 at 6:41
    
vnoremap p "_dP stop working for me in select mode, but vnoremap <leader>p "_dP does work – whitesiroi Nov 5 '15 at 10:22

In addition to the standard buffer, you can yank text into named buffers, and then put from those named buffers. There are up to 26 named buffers you can use (one for each letter). Use double quotes and a letter to access a named buffer. Examples:

"dyy - Yank current line into buffer d.
"a7yy - Yank next seven lines into buffer a.
"dP - Put the contents of buffer d before cursor.
"ap - Put the contents of buffer a after cursor

Another cool thing, if you use a capital letter instead of lower case, i.e "Dyy the current line will be Appended to the buffer d instead of replacing it. More details in the O`Reilly book: http://docstore.mik.ua/orelly/unix/vi/ch04_03.htm

share|improve this answer
1  
Very cool thing. I knew about buffers, but didn't connect them with this problem. It is still cumbersome to "a everything, but okay. – bitmask Aug 10 '11 at 20:27

When you yank the text into the unnamed register*, a copy is also put into register 0. Each time you replace selected text, you can just paste from the 0 register. See

:help registers

In addition, if you are replacing a number of words with the same word, you can just move to the start of the word to be replaced and type .. That will repeat the last editing operation. See

:help single-repeat

* The storage locations that you yank into and put from are called registers. A buffer is the thing that you edit, usually a copy of a file from disk.

share|improve this answer

When using put in visual mode, the text you're replacing, wrong1, is overwritten by the contents of the 'unamed' register.

This actually works by 'putting' the register after the selection and then deleting the selection. The problem is that this deletion is now stored in the unnamed register and will be used for the next put action.

The solution, according to :h v_p, is to yank into a named register, such as "0y, then paste using "0p as many time as you need. It may be helpful to map <leader>y and <leader>p to use a named register, if this is something you do frequently.

:map <leader>y "0y
:map <leader>p "0p

for more help see:

:help v_p
:help map
share|improve this answer
    
This solution seems most usable, until something clever comes up from the vim itself. – Yugal Jindle Nov 13 '13 at 4:14

Pasting from "0 register is important to know, but you often want to replace many times. If you make it a repeatable action, you can use the . operator, as alluded to by garyjohn. It's explained on the vim wiki:

yiw     yank inner word (copy word under cursor, say "first". Same as above).
...     Move the cursor to another word (say "second").
ciw<C-r>0   select "second", then replace it with "first" If you are at the start of the word then cw<C-r>0 is sufficient.
...     Move the cursor to another word (say "third").
.   select "third", then replace it with "first". 
share|improve this answer

I need this so often, I wrote a plugin for that: ReplaceWithRegister.

This plugin offers a two-in-one gr command that replaces text covered by a {motion}, entire line(s) or the current selection with the contents of a register; the old text is deleted into the black-hole register, i.e. it's gone.

share|improve this answer

This is what i use for Windows pasting behavior which allows me to visually select text and paste clipboard contents to overwrite what was selected, without corrupting the clipboard contents in the process.

For full listing with more comments and credits for where parts of this came from, and other unrelated but sorta related tidbits see: http://pastebin.com/aBEsm5mV

" This function is a smarter version of "_d"+P or "_dp to handle special cases, as Kache first described.
function! DeleteAndPaste(mode)
    if a:mode == 'v'
        let mode = 'gv'
    else
        let mode = ''
    endif

    let delete = '"_d'

    let reg = '"+'

    let lastLineOfBuffer = line('$')
    let selectionEndLine = line("'>")
    let selectionEndLineLength = len(getline(selectionEndLine))
    let selectionEndColumn = col("'>")

    " Check which case executed with :messages
    "
    " Note: Set to 1 to enable debugging
    let debug_cases = 0

    " If buffer has one line and selection ends on the last character of the line or +1 by selecting the invisible eol character
    if lastLineOfBuffer == 1 && selectionEndLineLength > 0 && selectionEndColumn >= selectionEndLineLength
        let cmd = 'p'

        if debug_cases
            echom "Special-1"
        endif

    " If selection ends on the last non-\r\n or EOL character of the line
    elseif selectionEndLineLength > 0 && selectionEndColumn == selectionEndLineLength
        let cmd = 'p'

        if debug_cases
            echom "Special-2"
        endif

    " If selection ends on the last line of the buffer and selection ends on the last character of that line or +1 by selecting the invisible eol character
    elseif selectionEndLine == lastLineOfBuffer && selectionEndLineLength > 0 && selectionEndColumn >= selectionEndLineLength
        "SOURCE:  http://vim.wikia.com/wiki/Quickly_adding_and_deleting_empty_lines

        "Fixes bug where if the last line is fully selected and a paste occurs, that the paste appears to insert after the first character of the line above it because the delete operation [which occurs before the paste]
        "is causing the caret to go up a line, and then 'p' cmd causes the paste to occur after the caret, thereby pasting after the first letter of that line.
        "However this but does not occur if theres a blank line underneath the selected line, prior to deleting it, as the cursor goes down after the delete in that situation.
        call append(selectionEndLine, "")

        let cmd = 'p'

        if debug_cases
            echom "Special-3"
        endif

    " If the next line is blank, and selection ends on the last character of that line or +1 by selecting the invisible eol character
    elseif len(getline(selectionEndLine + 1)) == 0 && selectionEndLineLength > 0 && selectionEndColumn >= selectionEndLineLength
        let cmd = 'p'

        if debug_cases
            echom "Special-4"
        endif

    else
        let cmd = 'P'

        if debug_cases
            echom "Default case"
        endif
    endif

    execute "normal! " . mode . delete . reg . cmd

    " Move caret one position to right
    call feedkeys("\<Right>",'n')
endfunction

Usage Examples:

" p or P delete to black hole register before pasting
vnoremap <silent> p :<C-u>call DeleteAndPaste('v')<CR>
vnoremap <silent> P :<C-u>call DeleteAndPaste('v')<CR>

" MiddleMouse delete to black hole register before pasting
nmap <MiddleMouse> "+p " Changes default behavior from 'P' mode to 'p' mode for normal mode middle-mouse pasting
vmap <silent> <MiddleMouse> :<C-u>call DeleteAndPaste('v')<CR>
imap <MiddleMouse> <C-r><C-o>+

Note: The <C-u> before calling DeleteAndPaste(...) clears commandline which fixes an issue where the selecting of text puts :'<,'> into the commandline [just select something and press ':' to see it]
      and that resulted in weird pasting behavior for my function. All fixed with <C-u> before the call however.
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .