Replace word with contents of paste buffer?
Asked Answered
P

11

122

I need to do a bunch of word replacements in a file and want to do it with a vi command, not an EX command such as :%s///g.

I know that this is the typical way one replaces the word at the current cursor position: cw<text><esc> but is there a way to do this with the contents of the unnamed register as the replacement text and without overwriting the register?

Pinnatiped answered 18/3, 2010 at 15:43 Comment(1)
RESOLUTION: For my immediate need, I used 12yl to yank 12 characters and "_cw^r0 to replace a word. I was then able to use the . command to repeat the replacement throughout the file.Pinnatiped
M
141

I'm thinking by "paste" you mean the unnamed (yank/put/change/delete/substitute) register, right? (Since that's the one that'd get overwritten by the change command.)

Registers are generally specified by typing " then the name (single character) of the register, like "ay then "ap to yank into register a, then put the contents of register a. Same goes for a change command. In this case, if you don't want the text you remove with the change command to go anywhere, you can use the black hole register "_: "_cw. Then once in insert mode, you can hit ctrl-R followed by the register you want (probably ") to put in the contents of that register.

  • "* - selection register (middle-button paste)
  • "+ - clipboard register (probably also accessible with ctrl-shift-v via the terminal)
  • "" - vim's default (unnamed) yank/put/change/delete/substitute register.

Short answer: "_cw^R"

Edit: as others are suggesting, you can of course use a different register for the yank (or whatever) that got your text into the default register. You don't always think of that first, though, so it's nice to do a single change command without blowing it away. Though it's not totally blown away. There are the numbered registers "0 through "9:

Vim fills these registers with text from yank and delete commands.

Numbered register 0 contains the text from the most recent yank command, unless the command specified another register with ["x].

Numbered register 1 contains the text deleted by the most recent delete or change command, unless the command specified another register or the text is less than one line (the small delete register is used then). An exception is made for the delete operator with these movement commands: %, (, ), `, /, ?, n, N, { and }. Register "1 is always used then (this is Vi compatible). The "- register is used as well if the delete is within a line.

With each successive deletion or change, Vim shifts the previous contents of register 1 into register 2, 2 into 3, and so forth, losing the previous contents of register 9.

Mcevoy answered 18/3, 2010 at 15:56 Comment(1)
All right, think I've copied enough of the docs on registers into my answer yet? It's all there under :help registers.Mcevoy
S
50

Using the information in this post, I have formed this useful mapping. I chose 'cp' because it signifies "change paste"

nmap <silent> cp "_cw<C-R>"<Esc>

EDIT:

Also I took this a step further and supported any motion.

To get the equivalent of command above it would be cpw for "change paste word"

"This allows for change paste motion cp{motion}
nmap <silent> cp :set opfunc=ChangePaste<CR>g@
function! ChangePaste(type, ...)
    silent exe "normal! `[v`]\"_c"
    silent exe "normal! p"
endfunction
Southdown answered 18/3, 2011 at 19:57 Comment(5)
The <silent> causes it to not work for me...any idea why that would be? I'm a n00b at mappings & functions.Bridesmaid
The only problem with this is that you can't choose a register to paste with... but in that case I suppose you could just cw and use CTRL+RFrankenstein
There might be a better way to add register naming but the following works for me: nmap <silent> cp :let g:currentRegister=v:register<cr>:set opfunc=ChangePaste<CR>g@ function! ChangePaste(type, ...) silent exe "normal! `[v`]\"_c".getreg(g:currentRegister) endfunctionFrankenstein
@eventualEntropy this works well for replacing lines, how can I make this work for words instead of lines, I am still learning vim. Thanks for the help.Gloze
@XavitojCheema I don't even remember making that comment, haha. But as it turns out, I've actually since wrote a plugin to provide this functionality (github.com/svermeulen/vim-easyclip)Frankenstein
D
37

If your cursor is on the word you want to replace with the contents of the unnamed register, you can use viwp. v switches to visual mode, iw selects the inner word, and p puts the contents of the register in its place.

In practice, when I need to replace one word (function name, etc.) with another, I'll move to the one to use as a replacement, yiw to yank the inner word to the unnamed register, then move to the word I'm replacing, and viwp to replace it. Pretty quick way of substituting one word for another. If you searched (/) for the word you're replacing to get to it, you can then just hit n to get to the next occurrence you need to replace. Obviously no substitute for using :%s/find/replace/g, but for a couple of quick substitutions it can be handy, especially if you already have the new word in a register.

Deviationism answered 23/1, 2014 at 20:43 Comment(2)
I'm surprised this isn't the accepted solution: all of the above, while more flexible in some edge cases, are much more verbose for simply ‘swapping the current unnamed register in for a selection somewhere,’ which is the situation the original asker came here for.Davenport
This is very useful and intuitive.Lyra
N
35

You can use the visual mode of vim for this. e.g. copy a word: ye and then overwrite another one with the copied word: vep

Nathan answered 2/8, 2010 at 18:48 Comment(2)
This works, but it should also be noted that the visual paste overwrites the yank buffer for the newly deleted text.Southdown
You can yank a word to a register "1yw and use it where you want with "1vep ? Worked for me....Sadick
W
7

If you make use of a named register (ie. use "ay or "ad, etc., to fill your paste register), you can do something like

cw<CTRL-R>a<esc>

Which will replace the word with the contents of register a. As far as I can tell, you can't use the default register because when you cw it'll be filled with the word that was cut by that command.

Wiley answered 18/3, 2010 at 15:56 Comment(2)
You can use the default register! Check out my answer.Mcevoy
or you can do ciw<CTRL-R>a<esc> if you don't want to first go to the beginning of the wordWexler
R
2

Do you mean the system paste buffer or the vi register?

If you want to use the system paste buffer then you are fine and could do dw"+P - " chooses a register, and "+ is the system paste buffer.

Otherwise copy into the non-default register with say "ay to copy into register a and then to replace something do dw"aP

Rechabite answered 18/3, 2010 at 15:58 Comment(2)
Thanks, Hamish. I tried that, but dw deletes trailing whitespace after what I would consider the "word," whereas cw only changes the word. For that reason, dw won't work for me.Pinnatiped
In that case de should work for you - it will delete to the end of this word, while dw will delete to the start of the next word.Rechabite
H
2

You can use yw to yank the word, then you can change the word with yanked word by viwp to yank inner word and paste previously yanked word.

Haler answered 13/12, 2014 at 9:4 Comment(0)
S
1

If you use neovim you can use P in visual mode, for example

viwP

which will overwrite the current word with the content of the " register without changing the register.

It also works with other registers:

"aviwP

will replace the word with content of register "a

See https://neovim.io/doc/user/change.html#v_P

Selfconfessed answered 27/7, 2023 at 17:6 Comment(0)
C
0

You can use registers for that:

first place replacement text in register <mark some text>"ay

where a is register name

then you can use that register in replacement

ve"ap

Canzone answered 18/3, 2010 at 15:58 Comment(1)
Unfortunately, I couldn't simply repeat the last, paste operation via ., which is another thing I wanted to do. Thanks, though. Much appreciated.Pinnatiped
J
0

Or you could do Shift+v-p (select the whole line and paste in its' place)

Jeraldjeraldine answered 22/12, 2011 at 19:25 Comment(1)
or pdw ... Don't you love vim? :PJeraldjeraldine
R
0

I see a lot of variation but i'm always looking for the laziest way to do it...

Anywhere on the word you just changed and want to copy over : yiw

Move to the first word you when to change/paste : viwP

And if other need the same treatment : .

The trick is upper case P doesn't replace the default register with the just deleted text.

Rumba answered 21/1 at 2:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.