34

When I have to replace a word with another word I yank before, I usually use a workflow which seems unnatural to me:

Let's say I have this text:

foo bar buzz

And I want to yank foo and replace bar with what I yanked before.

After yanking foo, I see the following options:

Option 1

  1. Place the cursor on bar with w

  2. Put foo in front of bar with P

  3. Put the cursor on the b of the remaining bar and delete the word with de

Option 2

  1. Put the cursor on bar with w

  2. Use de to erase bar

  3. Put the content of the register 0 with "0P (since I erased bar, foo isn't accessible anymore with a simple p)

Both ways seems over-complicated to me and I'm sure there is a more efficient way to achieve this action but I can't find how. This idea would be to combine the delete and the put actions in only one, or at least avoid to keep the deleted word in the yank register so as I can put the desired word with a simple p.

Also I know the replace mode triggered with R but it doesn't allow to put what was yanked.

TL;DR: How to replace a word with the content of the yank register?

5 Answers 5

39

Assuming you've already yanked foo with ye or something similar, and that the cursor is somewhere on foo, you can use Wvep:

  • W to go to bar (this is obviously optional and will depend on the current cursor position);
  • v to start visual mode;
  • e to go to the end of the word (you can also use other motions here, like iw);
  • p to paste foo; this will replace the current visual selection (which is put in the unnamed register, "").
2
10

EDIT 5 years later I had forgotten about this question but it turns out that the perfect solution for me is vim-subversive which provides two new operator motions to make it easy to perform quick substitutions.

I installed the plugin and added this to my config:

nmap gc  <plug>(SubversiveSubstitute)

this created a new command like y or p or d named gc which delete the text targeted by the motion without putting it in the unnamed register and replace it with the content of the unnamed register.

Beware, this command is so natural that it quickly becomes essential in your worklow and you will miss it a lot when you're not on your config.

So after having Martin's answer accepted for 5 years I'm changing to accept this one because it's the solution I've been using daily.


Original answer

I have found another way to do it, it is a little bit similar to the option 2 but it has the advantage of not messing the state of the registers.

The idea is to use the "black hole register": This register is accessible via "_ and has the particularity that you can write into it but not read from it, so like a black hole this register makes totally disappear anything which goes into it. Here we can use it so foo stays in the yank register even after bar deletion.

With this solution the worflow after yanking foo would be:

  • Going to bar with W (or any needed word of course)
  • Using the "black hole register" to delete bar with "_de
  • Putting foo from the yank register with P. The yank register still contains foo since bar went into the black hole.

I'm not sure that's is a better solution than @Martin's one (In term of vimgolf @Martin wins) but I didn't know about the black hole register and I thought some might be interested to know it.

1
  • 1
    I mostly like this answer for the example use of the black hole register "_de, so I'm glad you kept the original answer :)
    – icc97
    Nov 7, 2022 at 17:41
3
  1. Go to start of "foo". Press yiw. That yanks the inner word.

  2. Go to "bar" pressing the letter w. Then select it and yank back: viw"0p

I use ciw and yiw a lot.

2
  • 4
    The use of text objects like iw is interesting but your solution is actually the same as @CarpetSmoker's one: visually selecting the second word and put the first one. I also think that your solution would work with a simple p instead of using "0 register.
    – statox
    May 25, 2015 at 16:05
  • @statox using "0p instead of p is useful because you can do it repeatedly to paste the yanked word. p uses the default register which gets filled with the word that was replaced by the paste - which is useful for swapping but not for copy-pasting over multiple values.
    – icc97
    Nov 7, 2022 at 17:53
0
  • When the cursor is anywhere on the word,

    • yiw - yank the word and store it in 0 register.
  • Go to the target word to be replaced

    • ciw will delete the word and put you in insert mode.
    • ctrl-r. A " will pop up asking the register to be invoked.
    • 0 will paste the yanked word.

Yanked words are (normally!) stored in 0 register. See :registers to view the stored buffers. This may seem a lengthy procedure, IMHO this opens the door to the much more sophisticated register tricks.

0

Yank the "replacement" word into a named buffer, for this example I will use "r for 'replacement'.

This is as easy as "rye!

Yank to the (e)nd of the word, to avoid the extra space.

For an example I will change 'bad' to 'Good', using nvi-1.81.6. First I get the good with "rye:

Good. << "rye

On another line I want to change "bad" to "Good."

Move to the word you wish to have replaced (/bad). Now that you are on the word, run your vi command sequence: mnemonic derp!

de"rP
  • de == delete to end of word

  • "rP == put register r before cursor

Of course this could all be combined into map(s) or macros.

I imagine there is also a way to to do it with a ex command but it is not coming to mind.

Works on nvi and Heirloom vi, so it should work anywhere. You may need to play with the actual yank and put to fit your needs, depending on your vi implementation. For example, on my compiled Heirloom vi [Version 4.1.3 (gritter) 11/14/16] "rye needs to be "ryw. But it gives you the idea. I am not certain which behavior is compliant, but I am guessing it is nvi. I wish there was a "One True vi" to validate behavior against, like the One True AWK.

1
  • Vi's Command mode is also called Normal mode, and this site is not purely about vi; it includes vim/neovim in scope as well.
    – D. Ben Knoble
    Mar 21, 2021 at 16:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.