Vim: Quickly select rectangular blocks of text in visual block mode

I am looking for a quick way to select a block of text in visual block mode. I am dealing with files of this kind:

aaaa bbbb cccc aaaa bbbb cccc aaaa bbbb cccc dddd Xeee ffff dddd eeee ffff dddd eeee ffff gggg hhhh iiii gggg hhhh iiii gggg hhhh iiii 

My goal is to select the middle block in visual block mode. I would do:

  • Go to the corner (where is X)
  • Ctrl-v
  • 'e' to expand the selection to the end of the block.
  • 'jj' or '2j' to expand the selection down to the bottom of the block.

I am looking for an alternative (4) that, like "e", will move to the last line of the block. In this simple example, "jj" is not too inconvenient, but sometimes these are large blocks.

There is a similar question here, but this involves skipping a predetermined number of lines. Is there a way to do this, again analogous to "e", but moving along the rows, not the column? Thanks!

+7
vim
source share
3 answers

Starting with X , you can do this with <Cv>}kee :

  • <Cv> - start phased visual mode
  • } - skip to the end of the paragraph (this movement presumably provides the advantage of this rather involved combo).
  • k - one above to exclude an empty string
  • ee - move the cursor from the first column to the end of the indoor unit.
+5
source share

I had fun trying to make the "select Visual block around cursor" function.

 function! ContiguousVBlock() let [lnum, vcol] = [line('.'), virtcol('.')] let [top, bottom] = [lnum, lnum] while matchstr(getline(top-1), '\%'.vcol.'v.') =~# '\S' let top -= 1 endwhile while matchstr(getline(bottom+1), '\%'.vcol.'v.') =~# '\S' let bottom += 1 endwhile let lines = getline(top, bottom) let [left, right] = [vcol, vcol] while len(filter(map(copy(lines), 'matchstr(v:val,"\\%".(left-1)."v.")'),'v:val=~#"\\S"')) == len(lines) let left -= 1 endwhile while len(filter(map(copy(lines), 'matchstr(v:val,"\\%".(right+1)."v.")'),'v:val=~#"\\S"')) == len(lines) let right += 1 endwhile call setpos('.', [0, top, strlen(matchstr(lines[0], '^.*\%'.left.'v.')), 0]) execute "normal! \<CV>" call setpos('.', [0, bottom, strlen(matchstr(lines[-1], '^.*\%'.right.'v.')), 0]) endfunction nnoremap <Leader>vb :<CU>call ContiguousVBlock()<CR> 

You can try it with <Leader>vb : it should select any adjacent rectangle with no spaces around the cursor. A vertical axis is preferred.

I may improve it later, but now you can try it if it solves your problem if you want.

As an alternative to my home attempt, you can try the popular textobj-word-column plugin. It provides text objects ac ic ac ic to select a column of words or WORD.

+4
source share

Launch visual mode with v . Then select the inner paragraph with ip . Enter visual block mode with <Cv> . Now just go to the end of the block with e if necessary.

Starting at the bottom right block, it's the same thing, but use w instead of e .

+2
source share

All Articles