25

I would like to paste a column of text at the end of irregular-length lines.

For example, I would like to paste the following:

SRR447882.fastq.gz
SRR447883.fastq.gz
SRR447944.fastq.gz

at the end of these lines:

TIL01_
TIL01_
TIL04-TIP285_

Many times in the past, I simply create enough space on the first line that pasting will not come before the end of the existing text in the longest line. But then I need to go back and remove whitespace.

I have tried googling "vim column paste irregular length rows" and similar queries.

Christopher Bottoms
  • 11,218
  • 8
  • 50
  • 99

5 Answers5

44

You could try to do the following four steps:

  1. block-wise select the first 3 lines (you want to paste later), and press y
  2. line-wise select (V) the 3 lines ending with _, press :right
  3. then move cursor to the end of the first line($), paste the yanked text
  4. gv re-select the lines, press :left

It looks like this:

enter image description here

Kent
  • 189,393
  • 32
  • 233
  • 301
  • 4
    Nice example of the `:right`, `block paste`, `:left` transform. – Peter Rincker Nov 18 '13 at 14:52
  • Oops, I did not see that the text to paste was not the same line repeated. Nice gif btw :) – Zoneur Nov 18 '13 at 14:53
  • @Zoneur Why don't you repost your answer? (with corrections, of course) You got me thinking about macros, which is what I ended up doing before I saw Kent's answer. I don't know what I didn't think of macros (I use them all the time). I guess I was too focused on cut/paste itself. – Christopher Bottoms Nov 18 '13 at 15:00
  • I deleted my answer because it does not solve your problem and I actually don't know how to do it using macros. I found [this](http://stackoverflow.com/questions/10760326/merge-multiple-lines-two-blocks-in-vim) other answer though that merges two blocs, but is more complicated than Kent's solution. – Zoneur Nov 18 '13 at 15:07
  • @Zoneur A macro could copy from one block, move down to the corresponding line in the other block, paste at the end of the line, then return to the line just below the the starting point in the other block. – Christopher Bottoms Nov 18 '13 at 15:14
  • 2
    There are some good answers in the [Merge multiple lines](http://stackoverflow.com/questions/10760326/merge-multiple-lines-two-blocks-in-vim) post. I personally like ib.'s answer: `:1,g/^/''+m.|-j!`. Which would solve this question as well although I believe the right/paste/left method is a bit easier to remember later. – Peter Rincker Nov 18 '13 at 15:19
  • @ChristopherBottoms Thanks, I managed to do it :) Restored my answer as you suggested. – Zoneur Nov 18 '13 at 15:31
  • @ChristopherBottoms I thought there were variable lines between your two blocks of text. If the two blocks were continuous or there are fixed (relatively small) number of lines in between, it could be done by macro. – Kent Nov 18 '13 at 15:37
  • @ChristopherBottoms please let me know if you are looking for a Macro only solution. I could post a macro answer. – Kent Nov 18 '13 at 15:40
  • @Kent +1. I really like your answer; don't change it. It's the one I'd use if vim didn't get really slow when I try using `:right`. – Christopher Bottoms Nov 18 '13 at 18:45
  • 5
    Cool demo, how did you record that? – mowwwalker Nov 18 '13 at 19:11
  • 4
    is this answer so bad that it deserves a downvote? @downvoter, mind to leave a comment so that others can learn things? – Kent Feb 05 '14 at 22:46
  • If you have 1st piece of code various line length it's better to alight it right also so you could use line-wise selection. But later you will have a lot of extra spaces inside of lines. Could this be also solved? – VladSavitsky Jul 30 '20 at 08:34
  • @VladSavitsky perhaps you can post a new question with an example, it is a little bit hard to imagine what text do you have. – Kent Jul 30 '20 at 09:11
6

You can do it like this:

  • Start on the first line of the second block
  • qq, start recording the q macro
  • 4k, go up four lines
  • d$, delete till the end of line
  • 4j, go back to the previous line
  • $p, paste the line at the end of the line
  • q, stop recording the macro
  • jVG, go down one line and select the remaining lines
  • :norm! @q, apply the macro to the selection

It does however leave space where the previous text was. @Kent one's is still easier.

Zoneur
  • 1,101
  • 9
  • 20
  • Thanks! That's what I ended up using. Since it's just using macros, there's nothing extra for me to remember. I agree that Kent's solution looks nicer; but, for some reason `:right` seems to slow my vim interpreter down so much that it is unbearable. Your solution is the one that worked in my situation. – Christopher Bottoms Nov 18 '13 at 18:55
  • @ChristopherBottoms another macro solution: `ddma2jpkJx'a` cursor at the first `SRR..` line. – Kent Nov 18 '13 at 20:27
4

My UnconditionalPaste plugin has (among others) gBp / gBP mappings that paste register contents as a minimal fitting (not rectangular) block with a jagged right edge.

demo

enter image description here

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
1

Step 1 - goto to the start of the SPP... lines, then start Visual mode linewise with V (capital V), press j two times to get the desired lines selected then press y.

Step 2 - goto the start of the TIL0... lines, then start Visual mode linewise with V (capital V), press j two times to get the desired lines selected then type...

:s;$;\=' ' . split(@")[line('.')-line("'<")];g`

and press Enter.

cforbish
  • 8,567
  • 3
  • 28
  • 32
0

Here's another way to do it with a different feel to it:

set ve=all to permit insert/paste at arbitrary columns past eol. Block-copy your source text, then at your first target line paste it with 100|P (100 being any column number longer than your target lines), then :'[,']s, *\%100c,,

If you do p instead of P you'll get a space separator.

jthill
  • 55,082
  • 5
  • 77
  • 137