0

Is there a way to bind I and A in visual mode and visual line mode to switch the selected region to a visual block selection with the same boundaries?

I'd like to be able to use visual line mode to select a group of lines and then use I or A to add text before or after all of the lines.

For instance, in the following file (with line numbers)

  1 a
  2 b
  3 c
  4 d
  5 e
  6 f
  7 g
  8 h

The sequence <esc> gg V G I # <space> <esc> produces

  1 # a
  2 b
  3 c
  4 d
  5 e
  6 f
  7 g
  8 h

and I'd like it to produce this, just as visual block would.

  1 # a
  2 # b
  3 # c
  4 # d
  5 # e
  6 # f
  7 # g
  8 # h

I've tried using the following keybinding to switch to visual block mode right before inserting in every mode except visual block, but it loses the selection region.

vnoremap <expr> I   mode()=~?'\cv' ? 'I' : '<c-v>I'
vnoremap <expr> A   mode()=~?'\cv' ? 'A' : '<c-v>A'
2

Your attempt was close, but there are two problems I see:

  1. I'm sure you already know this, since you mentioned it in your comment, but mode() will return <C-v> in visual block mode, not \cv.

  2. Pressing <C-v> from visual line mode will always leave the cursor where it is. And <C-v>I will not put the text at the beginning of the line, but right before the cursor. Similarly with <C-v>A. So you'll want to use either 0 or $ to make sure your cursor is where you want it.

This should do what you're looking for:

vnoremap <expr> I mode()=~? '<C-v>' ? 'I' : '<c-v>0I'
vnoremap <expr> A mode()=~? '<C-v>' ? 'A' : '<c-v>$A'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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