tags:

views:

3647

answers:

13

Using vim I often want to replace a block of code with a block that I just yanked. But when I delete the block of code that is to be replaced, that block itself goes into the register which erases the block I just yanked. So I've got in the habit of yanking, then inserting, then deleting what I didn't want, but with large blocks of code this gets messy trying to keep the inserted block and the block to delete separate.

So what is the slickest and quickest way to replace text in vim?

  • is there a way to delete text without putting it into the register?
  • is there a way to say e.g. "replace next word" or "replace up to next paragraph"
  • or is the best way to somehow use the multi-register feature?
+4  A: 

Well, first do this command:

:h d

Then you will realize that you can delete into a specific register. That way you won't alter what is in your default register.

EBGreen
+3  A: 

For the specific example that you gave, if I understand the question then this might work:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)
EBGreen
+3  A: 

If you're using Vim then you'll have the visual mode, which is like selecting, but with the separating modes thing that's the basis of vi/vim.

What you want to do is use visual mode to select the source, then yank, then use visual mode again to select the scope of the destination, and then paste to text from the default buffer.

Example:

In a text file with:

1| qwer
2| asdf
3| zxcv
4| poiu

with the following sequence: ggVjyGVkp you'll end with:

1| qwer
2| asdf
3| qewr
4| asdf

Explained:

  • gg: go to first line
  • V: start visual mode with whole lines
  • j: go down one line (with the selection started on the previous lines this grows the selection one line down)
  • y: yank to the default buffer (the two selected lines, and it automatically exits you from visual mode)
  • G: go to the last line
  • V: start visual mode (same as before)
  • k: go up one line (as before, with the visual mode enabled, this grows the selection one line up)
  • p: paste (with the selection on the two last lines, it will replace those lines with whatever there is in the buffer -- the 2 first lines in this case)

This has the little inconvenient that puts the last block on the buffer, so it's somehow not desired for repeated pastings of the same thing, so you'll want to save the source to a named buffer with something like "ay (to a buffer called "a") and paste with something like "ap (but then if you're programming, you probably don't want to paste several times but to create a function and call it, right? RIGHT?).

If you are only using vi, then youll have to use invisible marks instead the visual mode, :he mark for more on this, I'm sorry but I'm not very good with this invisible marks thing, I'm pretty contaminated with visual mode.

maeghith
+54  A: 

To delete something without saving it in a register, you can use the "black hole register":

"_d

Of course you could also use any of the other registers that don't hold anything you are interested in.

Christian Berg
+3  A: 

Text deleted, while in insert mode, doesn't go into default register.

but deleting any significant amount of text in default mode is SLOW
Hamish Downer
+3  A: 

For 'replace word', try cw in normal mode.

For 'replace paragraph', try cap in normal mode.

Swaroop C H
+1 for being the best answer to the second question of the original post.
Jabir Ali Ouassou
For 'replace *up to* next paragraph', try `c}` in normal mode.
Jabir Ali Ouassou
+13  A: 

Yep. It's slightly more convoluted than deleting the "old" text first, but:

I start of with..

line1
line2
line3
line4

old1
old2
old3
old4

I shift+v select the line1, line 2, 3 and 4, and delete them with the d command

Then I delete the old1-4 lines the same way.

Then, do

"2p

That'll paste the second-last yanked lines (line1-4). "3p will do the third-from-last, and so on..

So I end up with

line1
line2
line3
line4
dbr
I never knew this. This is really convenient! +1
nickelleon
If you select lines with <Shift-v> you delete them with just d, not dd
Heikki Naski
@Heikki Good point, fixed
dbr
+2  A: 

In the windows version (probably in Linux also), you can yank into the system's copy/paste buffer using "*y (i.e. preceding your yank command with double-quotes and asterisk).

You can then delete the replaceable lines normally and paste the copied text using "*p.

JayG
+4  A: 

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

E.g. we yank "foo" and delete "bar" - the registry 0 still contains "foo"! Hence "foo" can be pasted using "0p

alex2k8
+6  A: 

It's handy to have an easy mapping which lets you replace the current selection with buffer.

For example when you put this in your .vimrc

vmap r "_dP       // it's a capital 'p' on the end

then, after copying something into register (i.e. with 'y'), you can just select the text which you want to be replaced, and simply hit 'r' on your keyboard. The selection will be substituted with your current register.

Explanation:

vmap - mapping for visual mode
"_d - yank current selection into "black hole register"
P - paste
For a more advanced version, check: http://stackoverflow.com/questions/290465/vim-how-to-paste-over-without-overwriting-register/290723#290723
Luc Hermitte
+2  A: 

I put the following in my vimrc:

noremap  y "*y
noremap  Y "*Y
noremap  p "*p
noremap  P "*P
vnoremap y "*y
vnoremap Y "*Y
vnoremap p "*p
vnoremap P "*P

Now I yank to and put from the clipboard register, and don't have to care what happens with the default register. An added benefit is that I can paste from other apps with minimal hassle. I'm losing some functionality, I know, but I just can't keep track of more than one register/clipboard anyway.

+1  A: 

I often make a mistake when following the commands to 'y'ank then '"_d'elete into a black hole then 'p'aste. I prefer to 'y'ank, then delete however I like, then '"0p' from the 0 register, which is where the last copied text gets pushed to.

Clueless
+1  A: 

To emphasize what EBGreen said:

If you paste while selecting text, the selected text is replaced with the pasted text.

If you want to copy some text and then paste it in multiple locations, use "0p to paste. Numbered register 0 contains the text from the most recent yank command.


Also, you can list the contents of all of your registers:

:registers

That command makes it easier to figure out what register you want when doing something like dbr's answer. You'll also see the /,%,# registers. (See also :help registers)


And finally, check out cW and cW to change a word including and not including an trailing space. (Using capital W includes punctuation.)

pydave