51

Say I have a block of text like this:

// Comment1
// Comment2
// Comment3

And I want to append each of these lines to the end of 3 corresponding lines of code:

foo = 1;
bar = 2;
baz = 3;

So that the end result is

foo = 1; // Comment1
bar = 2; // Comment2
baz = 3; // Comment3

Is there an easy way to do this in Vim?

karel
  • 13,390
  • 26
  • 45
  • 52
Tim
  • 621
  • 1
  • 6
  • 5
  • @Flimzy, unfortunately no. From time to time comments like yours appear in Vim questions, but check this: http://meta.stackexchange.com/q/25925/160504 – sidyll Jun 21 '11 at 18:26
  • The better community for this question is https://vi.stackexchange.com/ – thinwybk Nov 23 '18 at 15:08

4 Answers4

53

Use visual block mode (Ctrl+v) to select one set of lines, then either y or d them.

Then, if you selected the foo, bar, baz lines use visual block mode again to select the first column of the comment lines and then Shift+p them into place (or if you selected the comment lines, select the last column of the foo bar baz lines and p them into place.

Getting the hang of positioning might take a bit of practice, but when you've got the knack you'll be flying. When you've got a block selected you can also use Shift+A to append e.g. spaces to the block (when appending, the new text will only appear in the top line, but when you hit esc it will magically appear in all the selected lines). Similarly, Shift+i will do the same at the beginning of the selected block on each line.

You'll need to clean up the empty lines afterwards though.

There's also a great vimcasts episode showing these techniques in more detail.

actionshrimp
  • 646
  • 5
  • 4
  • 1
    I find this solution coupled with `:set ve=all` to be very versatile. I personally use the UnconditionalPaste plugin (http://www.vim.org/scripts/script.php?script_id=3355) as it fits my need a bit better. – Peter Rincker Jun 21 '11 at 18:32
  • 3
    This does not work for me for some strange reason. My vim will still behave like I am using visual line mode when pasting (adding newlines etc.) – Dogemore May 01 '20 at 03:01
  • Be aware of the newlines and make sure you use "visual block" (Ctrl+v) to select the second block that you want to copy to the first one. If you use "visual lines" (Shift+v) to copy the second block, it will also copy the "end of line" character. – Stardust Aug 29 '23 at 14:18
1

Well, if it is easy or not, you tell me. Navigate to // Comment 1, hit dd to delete. Navigate to the line with foo = 1; and hit p, to paste in below the line. Move up to foo again, and hit J to join the row. Tada.

TLP
  • 119
  • 1
  • 6
0

If you have these two block in the same file use Ctrl+v to select the comments --> Ctrl+v 2j$y , then go the first line of the other block, press A+Space, then press p.

If your comments are in the clipboard run:

:call setreg('+',getreg('+'),'b')

then press A+Space and finally p.

NOTE: The setreg() command, the way we are using makes your clipboard clockwise, allowing you to paste it at the side of any block of the text.

You can view a gif where the guy uses the first approach slightly differently: https://codegrepr.com/question/how-do-i-paste-a-column-of-text-after-a-different-column-of-text-in-vim/

SergioAraujo
  • 251
  • 3
  • 6
0

The following will do exactly what you describe:

:%s@\(\w\s\+=\s\+\(\d\+\)\)@\=submatch(1) . " // Comment" . submatch(2)@

Depending on what you actually need done (as opposed to the example), in practice, it might be more straightforward to block-select the "// Comment1" etc. block (Ctrlv), yank (y), go to the end of the code block and paste.

Jeet
  • 296
  • 1
  • 6