6

I'm facing a behavior that I find unatural when trying to paste a block of text selected with visual block mode (<C-v>): I can't insert it between two lines without messing with the already existing line.

Here's an example:

If I have this file

abc
def
hij
klm

This is a text
on several lines
and this is another line

Let's say I want to put the first letters of each of the 4 first lines between the 2 others lines of text.

  • First I'll select the 4 letters: <C-v> 3j y
  • Then I put my cursor on the o of the last line
  • Finally I put my letters before my cursor with P

The result I get is:

This is a text
aon several lines
dand this is another line
g
j

Where as what I expected was

this is a text 
a
d
g
j
on several lines
and this is another line

So it means that each time I want to past a block this way I have to insert the corresponding number of empty lines before I past which is pretty unatural in my opinion.

I found a vim tip suggesting to use 1vp to select a corresponding number of lines before pasting but that allows a replacement not an insertion of the block.

So my question is: What is the good way to insert a visually selecting block between two existing lines?

Also I once saw a plugin (which I can't remember the name) which "improved" visual block mode, but I'd like not to add a plugin just to enable this behavior.

1

3 Answers 3

5

That plugin you're referring to might be my UnconditionalPaste plugin, which provides (among many related other commands) the exact glp (force linewise paste) command you're looking for here.

As its author, I surely think the plugin provides very helpful functionality that warrants installing it, but you can achieve the same via a simple built-in command. After yanking, execute:

:call setreg('', '', 'ac')

Then paste with P. This changes the type of the default register from blockwise to characterwise. (As there's no setregtype() function, it does this by appending (a) nothing ('') to the register.)

The setreg() approach also works for other such conversions (e.g. characterwise to linewise with 'al' parameter.)

For your particular example, there's an even shorter (but less general) way:

:put!

will always paste in new lines.

3
  • Thanks a lot for your tips (I'll also check your plugin)! Your answer leads me to another question (I don't know if I should create a new one or ask it here): let's say I want to map P to call setreg() and then put but only when I made a block selection is there a way to create such a mapping? I can't create it only in visual mode because it is not relevant and create it in normal mode would override P each time which is not what I want neither.
    – statox
    Commented May 18, 2015 at 12:00
  • You can use getregtype() to check whether the register contains a blockwise selection. But in my opinion, blockwise paste can be useful, too, so I would recommend a separate mapping. Commented May 18, 2015 at 12:31
  • Yes I think you're right. Anyway I checked your plugin and I think I will simply use that it is the most convenient. Thanks again for your answers!
    – statox
    Commented May 18, 2015 at 13:38
6

You can get the behavior you want with: OCtrl+R".

Ctrl+R in Insert mode pastes a register -- in this case, the default " register. Since you're in Insert mode, it ignores the block-ness of the buffer.

1
  • 1
    Thats is a totally valid way to do it and I didn't know <kbd>Ctrl+R</kbd>. So thats a good answer thank you.
    – statox
    Commented May 20, 2015 at 7:41
0

The plugin tpope/vim-unimpaired also comes with some useful linewise paste mappings:

PASTING                                         *unimpaired-pasting*

These are experimental:

*>p*    Paste after linewise, increasing indent.
*>P*    Paste before linewise, increasing indent.
*<p*    Paste after linewise, decreasing indent.
*<P*    Paste before linewise, decreasing indent.
*=p*    Paste after linewise, reindenting.
*=P*    Paste before linewise, reindenting.

|]p|, |[p|, |[P|, and |]P| have also been remapped to force linewise pasting,
while preserving their usual indent matching behavior.

                                                *[op* *]op* *yop*
A toggle has not been provided for 'paste' because the typical use case of
wrapping of a solitary insertion is inefficient:  You toggle twice, but
you only paste once (YOPO).  Instead, press [op, ]op, or yop to invoke |O|,
|o|, or |0||C| with 'paste' already set.  Leaving insert mode sets 'nopaste'
automatically.
1
  • So I did forgot I asked this question 8 years ago :D Despite the huge popularity of this unimpaired I never ended up installing it, for this specific use case I got the habit of using ctrl+r " but unimpaired seems like a good solution too
    – statox
    Commented Apr 20, 2023 at 7:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.