4

Here is what I want to do. Consider the text

abcvvxyz
abcvvxyz
123456
123456

I would like to copy the v block and paste it over the 45 block to get the following:

abcvvxyz
abcvvxyz
123vv6
123vv6

What I know I can do is: <C-v> for visual-block mode, select the v block (jl), and yank y.

Then go to the first 4, select the 45 block (<C-v>lj) and paste p. This will have the desired effect.

However, I would like to achieve the same without the need to visually mark the target block. It is easy enough in case of two lines and two columns, but with larger blocks I always get it slightly wrong. I would like to put my cursor in the top corner of the intended target and let vim do the rest: if the yanked block is 2 x 2, then replace the following 2 x 2 block whose left upper corner is my current cursor position.

2
  • Interesting :-) I'm curious to know in which context you need that. Commented Apr 19, 2023 at 9:24
  • 1
    Working on markdown tables and moving cell contents around, while trying to keep the column boundaries aligned between the lines.
    – January
    Commented Apr 19, 2023 at 12:15

2 Answers 2

10

Simply (assuming we are on the topleft v):

  • Ctrl-vjly (yank the block)
  • jj (move to start of next block)
  • 1v (select a block the same size as our last visual selection)
  • p (paste)

See :help CTRL-V, which takes a [count] whose behavior is like with v:

            With [count] select the same number of characters or
            lines as used for the last Visual operation, but at
            the current cursor position, multiplied by [count].
            When the previous Visual operation was on a block both
            the width and height of the block are multiplied by
            [count].
            When there was no previous Visual operation [count]
            characters are selected.  This is like moving the
            cursor right N * [count] characters.  One less when
            'selection' is not "exclusive".

Fortunately, 1v works to trigger Visual-block mode if that was the last mode, saving us an extra Ctrl press.

3
  • 3
    Thanks @Ben, I learned something :-) @January, my solution is a complex replacement of the standard 1vp Commented Apr 19, 2023 at 13:30
  • Perfect! Thank you so much
    – January
    Commented Apr 19, 2023 at 13:32
  • 1
    @VivianDeSmedt: yes, but on the other hand, I learned from your solution as well ;-)
    – January
    Commented Apr 19, 2023 at 13:32
2

I would do:

exe 'normal! ' .. "\<C-v>" .. (getregtype('"')[1] - 1) .. 'l' .. count(getreg('"'), "\<char-10>") .. 'jp'

Basically the code determine the size of your block selection:

  • getregtype('"')[1]
  • count(getreg('"'), "\<char-10>") + 1

It then emulate what you proposed to do manually but consider (correctly :-) ) error prone.

The code could be improved to verify that a block selection has been made.

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.