3

I have some long text on Yank var e.g. "Hello all how are you ?"

I have a rectangular selection between abc and ABC /a llC-vjj

a A
b B
C C

And I want to past my long text without having to type it

To get this:

a Hello all how are you ? A
b Hello all how are you ? B
c Hello all how are you ? C

From @christian-Brabandt I select (| is where my cursor is) not the line but characters like this:

|Hello how are you ?
vllllllllllllllllllly

then I put the cursor on 'a'

a A
b B
C C

and press 'p'

I got

aHello how are you ? A
b B
C C

So with this method I have to add a space with i <ESC>, go on b type pi <ESC> go on c` ...

Not optimal because not using the block selection ;(

user3313834
  • 189
  • 4
  • 2
    I would say: "Just hit p." But I guess that is not what you want. Could you please provide a example of the result you want to achieve? – Ralf Apr 14 '19 at 22:18
  • Depending on the register content, you might have to first set the register to blockwise or characterwise before pasting, e.g. like this (assuming your yanked text is in register a: call setreg("a", getreg("a"), 'v') – Christian Brabandt Apr 15 '19 at 08:19

2 Answers2

3

It is not very clear from the question, what the goal is (e.g. what the final result should look like). So let me describe what you can do.

First, store your text in register a:

:let @a='Hello all how are you ?'

A register does not only store text, it also remembers whether it has been used in line wise, character wise or block wise mode. You can influence this using the 3rd argument of the setreg() function.

Now with a sample like this:

a A
b B
c C

enter image description here

  1. Pasting in character wise mode

After 1), the register content will be in character wise mode, as :echo getregtype('a') confirms. So block selecting the empty space after the capital letters (1gg$<c-v>2j) and hitting "ap will result in: enter image description here

  1. Pasting in line wise mode

Change the register a to be linewise: call setreg('a', getreg('a'), 'l') Now, block select the empty space after the capital letters (1gg$<c-v>2j) and hitting "ap will result in: enter image description here

  1. Pasting in block wise mode

Change the register a to be linewise: call setreg('a', getreg('a'), 'b') Now, block select the empty space after the capital letters (1gg$<c-v>2j) and hitting "ap will result in: enter image description here

So you need to define, how register should be handled and you might need to change the register type if needed.

Note, there also exist plugins to make handling this easier. Ingo Karkat maintains a plugin UnconditionalPaste, that can be used to force pasting a register with a different type.

Christian Brabandt
  • 25,820
  • 1
  • 52
  • 77
  • Thank you for all the details, this is very helpful. +1. Sadly, this means I first followed your suggestion correctly: with gvim 7.4, the version I was using to test, the paste is only on the first line, even with the register in character mode. I now tested with gvim 8.1.1 and it works as you describe, pasting on each line as desired. I think it's time I update my gvim on all machines. – joanis Apr 16 '19 at 20:17
  • Just did some research, and it looks like you implemented Patch 7.4.199 making all this work. If I'm reading the doc correctly, this patch has been available since vim 8.0. – joanis Apr 16 '19 at 20:32
2

TL;DR

You can accomplish this by using q to record a sequence of operations and @ to replay it.

Assumptions

I think you want this output:

a Hello all how are you ? A
b Hello all how are you ? B
c Hello all how are you ? C

A paste like you describe would be quite a useful feature, I agree, but I did some tests and I don't see how to do it in my vim 7.4 installation.

Recording as a solution

The solution I found uses q to record pasting the line once, and then replaying the recorded commands twice:

Set the cursor on A and record doing the insertion once:

q1P6bjq

Explanation:

  • q1: start recording into register 1
  • P: insert the text - you could type it out, as well
  • 6bj: place the cursor on B to be ready to paste on the next line
  • q: stop recording

Then replay register 1 twice, or however many times are needed:

2@1

Before replaying, make sure the cursor is still on B, and things should work.

I agree, this is not nearly as nice as a block-duplicated paste as you describe in the question, but it works.

vim 8

PS: with Vim 8 or more recent, a simple paste over a block selection is likely to work. See @ChristianBrabandt's answer for more details.

joanis
  • 131
  • 4
  • I would add that you can execute a macro on lines matching a text. So say you have your Hello all how are you ? yanked in the " register, and you have a macro as the one described in this answer, you can do: :g/\w /norm! @1 Which will execute the macro on every lines matching the regex ^\w. This would avoid the 2@1 in case you have way more than 2 line to cover, and to not have to count them. – padawin Apr 15 '19 at 13:50
  • In my case, the macro I did to do it was 0a <c-o>P<esc> – padawin Apr 15 '19 at 13:52
  • Why are you saying there is no solution to achieve that. I can just make a visual-block between the small and capital letters and press p assuming that the line Hello all how are you ? is already on the unnamed register. – 3N4N Apr 15 '19 at 14:01
  • @klaus When I tried that, it pasted on the first line, not on all the lines. The rest of the visually selected block was deleted but not replaced. The problem is that I have one line in the buffer, not an actual block. – joanis Apr 15 '19 at 14:34
  • As mentioned in my comment, this happens because your register is not of type charwise. – Christian Brabandt Apr 15 '19 at 15:12
  • @ChristianBrabandt I tried to do what you said in your comment, but I can't make it work. Are you willing to write up an answer step-by-step? – joanis Apr 15 '19 at 15:23
  • @ChristianBrabandt A few more details: if I yank a one-line block, select a 3 line block and hit p, I get the paste results on the first line and erasing in the next two. I tried yanking a 2-line block and pasting it onto a 4-line block, and again no repetition, just pasting of 2 lines and erase of the last two. So if your approach works, I'd be really interested in more specific details. – joanis Apr 15 '19 at 15:45
  • @joanis as mentioned in my earlier comment, make use of the setreg() function to set the type of the register. – Christian Brabandt Apr 15 '19 at 15:51
  • @ChristianBrabandt As I said, I did, and no luck. Hence my hope you'll spell it out step-by-step, starting with the correct way to yank, the exact way to call that function, and the correct way to paste the results. – joanis Apr 15 '19 at 15:58