127
votes

At least once per day i have the following situation:

A: This line should also replace line X
...
X: This is line should be replaced

I believe that I don't perform that task efficiently.

What I do:

  • Go to line A: AG
  • Yank line A: yy
  • Go to line X: XG
  • Paste line A: P
  • Move to old line: j
  • Delete old line: dd

This has the additional disadvantage that line X is now in the default register, which is annoying if I find another line that should be replaced with A. Yanking to and pasting from an additional register ("ayy, "aP) makes this simple task even less efficient.

My Questions:

  • Did I miss a built-in Vim command to replace a line yanked before?
  • If not, how can I bind my own command that leaves (or restores) the yanked line in the default register?
17
This is my single biggest issue with Vim's editing model. I'd love to know a solution. A CUA editor distinguishes between cut and delete, so you just cut some text, then you can go delete and paste all you want. With Vim, any delete you make trashes your cut text. You end up using far more keystrokes than you would another editor. - Mud
@sehe I'm perfectly aware of registers, but that adds 4 keystrokes per cut/paste operation and requires more forethought. When you're doing a lot of editing, that adds up quick. - Mud
Other than saving a few bytes of memory, is there an advantage to using the black hole register as opposed to any other register? I would argue that any register can be a black hole register if you do not read back from it. - sleblanc

17 Answers

123
votes

Vp: select line, paste what was yanked

100
votes

What I would do :

  1. aG
  2. Y
  3. xG
  4. Vp

You don't have to leave normal mode, but it does yank the line. You can however use V"0p which will always put the line yanked in step 2.

45
votes

This has the additional disadvantage that line X is now in the default register, which is annoying if I find another line that should be replaced with A.

To delete text without affecting the normal registers, you can use the Black hole register "_:

"_dd
19
votes

Building on the answers that suggest using Vp or VP to paste over a line -- to avoid changing the contents of the yank register I find the most ergonomic command is simply:

VPY

13
votes
  1. yy
  2. j (move to the line you want to replace),and then
  3. Vp (uppercase v and then p, will replace with the yanked content)
9
votes

I would use commandline (Ex) mode and do the following two commands

:XmA
:Ad

This simply moves line X to just under A, then deleting A moves that line up

For example

:7m3
:3d
8
votes
  1. Move to the start of the first line.

  2. y, $ – copy the line without the linebreak at the end

  3. Move to the start of the target line.

    1. V, p – replace just one target line

    2. c, c, Ctrlr, 0, Esc – replace the target line with the original yank

  4. Move to the start of the next target line.

  5. . – repeats the command issued at 4.2.

Notes:

  • 4.1 is y, $ because if you do y, y or Y you will copy the linebreak, and Ctrlr0 actually adds the linebreak below your target line.

  • 4.2 replaces V p, which doesn’t work with repeat because technically the last action is delete, so . would just delete a line.

  • If anyone knows how to issue ‘replace current line with register’ from EX mode (command line), I would like to hear from you (and to know where you found the documentation). There may be a repeatable EX command which is faster than 4.2 and/or does not have the linebreak caveat.

6
votes

You can also do:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)
  • Doesn't create spaces or line ends.
  • Cursor is placed at the start of the copied text.

The same keys can be used to yank/paste more than one line.

V (in normal mode at what you want to yank)
(use jk to move the selection)
y (to yank the selection)
V (in normal mode at where you want to paste)
(use jk to move the selection)
p (to replace the selection with the yanked lines)
5
votes

Here's what I would do

  • Move beginning of line A, AG (where A is a line number obviously)
  • Yank line to some register, e.g. a (without new line). Type "ay$
  • Move to insert line, XG
  • Substitute line, S
  • Insert from register a, Ctrl-Ra
4
votes

You can use this with visual mode.

  • Go to line A: AG
  • Select the line with visual mode: VESC
  • go to line X: XG
  • Enter substitute mode for the line: S
  • Paste the line you copied: shift+insert (or whatever other you mapping you have for pasting from the clipboard).
3
votes

In light of the recent comment by cicld (thank you!), I see that I didn't grasp the original issue fully. Moving the line is not appropriate, but copying is (since the line is yanked.) So I would revise it to:

:1t20:20d_
  1. Copy the 1st line (:t command is an alias for :copy) after line 20 (will place it on line 21)

  2. Delete line 20, putting the deleted line into the 'blackhole' register (_) (i.e. not affecting the current yank buffer)

As mentioned in the recent comment, this will not affect the current cursor position.

2
votes

You can use this commands in Normal Mode:

:AmX | Xd

the m command is for m[ove], which moves the line number A after the line number X, if you want to copy instead of move the line, use co[py]. the d command is for d[elete].

You can move(copy using co) a range of lines using

:start,end m X
1
votes
  1. :ay (where a is the line number. Example :20y). This yanks a line(pun intended).
  2. Vp
1
votes

I find it easier to use Ex command for this; ex. to move line 9 to 46:

 :46|9m.|-1d

This will move the cursor to line 46, move line 9 below the current, then delete the previous line (since moved line is the current one).

Or using mark(s), using mark 'a':

:46ma a|9m'a|'ad
1
votes

I often have to Y one line and replace it in multiple places, each of which have a different value (which means that I can't do a regex).

Y to yank the desired original line

and then on every line that you'd like to replace, VpzeroY

0
votes

i would simple use the "Black hole" register:

given:

nnoremap < C-d > "_dd

the solution would be:

< C-d >yy

0
votes

If you only want to change part of the line you can do that this way:

Move to position of what part of text you want to copy

y,$ - Yank from cursor to EndOfLine

move to position where you want to replace

v,$,p - replace from cursor to EndOfLine with contents of register