0

assume you you have some text like this:


           <-------unknown area
           <-------blank lines
.....0.....<-------dot represent unknown character
.....1.....
.....*.....<-------unknown number of lines, the 6th column is not blank
.....3.....
.....4.....
.....5.....<-------your cursor at 5
.....6.....
.....7.....
.....*.....<-------unknown number of lines, the 6th column is not blank
.....9.....
.....0.....
           <--------blank lines
           <-------unknown area

what's the simplest way to select from 5 to the first or last 0 in visual block wise mode? Please don't use character value(such as /0 or ?0), don't assume there are 11 lines(such as 5j or 5k), don't assume there are 11 columns.

marked as duplicate by dedowsdi, Community May 10 at 14:16

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    I guess technically it's not a dupe because you're asking about selection rather than movement, but I think you should be able to adapt the answers to this older question to do this. – Rich May 10 at 13:43
  • And see also this related but different question. – Rich May 10 at 13:45
  • Thanks, love the accepted answer in the 1st question. – dedowsdi May 10 at 14:12
0

If I understood correctly (If you want to visual select from 5 to the end or beginning of the block), you can do it with:

{

to go to the beginning

and

}

to go to the end.

CF: :help {

And it can be done is visual or normal modes.

EDIT: Again, I am not sure to have properly understood the issue.

If you are trying to do a visual selection as follow:

enter image description here

I did with the cursor on 5 (which is on the 6th column):

<c-v>}k5l

Which puts me on visual mode (<c-v, ctrl + v), goes at the end of the paragraph (}, paragraphs are delimited with empty lines), go one line up (k, bringing at the beginning of the line), move of (n-1) chars to reach the column back (5l, to go to the 6th column).

If this is not what you are trying to achieve, can you please rephrase the question?

  • Can I know why the -1? – padawin Apr 12 at 14:22
  • So it's indeed a matter of If I understood properly as I started with. Your question before the editions (at the time I wrote the answer) sounded like "how to select until the next blank line before or after", which my answer covers. – padawin Apr 12 at 14:41
  • Are you trying to achieve something like that: imgur.com/a/htEGGrR (Visual selection until the last non empty line) ? – padawin Apr 12 at 14:44
  • 1
    @dedowsdi There is no need to be harsh, just because someone misinterpreted the question. Anyway I woud try <C-V>{w and <C-V>}b (assuming that the dot's in your question represent spaces). – Ralf Apr 12 at 14:54
  • 1
    I don't, but you know at which column your cursor is at the beginning, so you know of how many you have to move. Beside, instead of telling us what to not assume, you can add some clarity in your question and example. – padawin Apr 12 at 15:09
0

You can read the column number of the cursor by

g<C-G>

in your case the 5 is in column 6. Subtract 1 and use 5l to get from line start to the same column as the 5. To get the longest column that includes the 5 between the blank lines you can use

vip5l<C-V>o5l

With the following commands:

  • v get in visual mode
  • ip select inner paragraph, this is separated by the blank lines
  • 5l move the end cursor of the visual to 6th column
  • <C-V> change to visual block mode (see also <C-Q>)
  • o change to the next cursor of the block mode
  • 5l move the start cursor of the visual block mode to 6th column.
  • Thanks. Because bottom line might contain <tab>, i will use screen column. so the workflow is g<c-g> read screen column, <c-v>}k6|, it's too much effort for a daily workflow. – dedowsdi Apr 13 at 0:24
0

Built in normal commands such as <c-v>}k6| always require you to manually find current virtual column to finish the selection, that's unpleasant.

There are some plugins can be used to select vertical column:

I borrowed some idea from vim-vertical-move, <c-v>ic is pretty easy to memorize. I created following script to do the job:

" ov : o for omap, v for v map
" jk : j or k or jk. j for down, k for up.
" visuall block wisely select current column until blank line.
function! SelectScreenColumn(ov, jk) abort
  let [curVnum, curLnum, colLnum0, colLnum1, lnum] =
              \ [virtcol('.')] + repeat([line('.')], 4)
  " do nothing if cursor in blank
  if GetV(curLnum, curVnum) =~# '\v\s'
    if a:ov ==# 'v' | exec 'normal! ' | endif | return
  endif

  " get column end
  if stridx(a:jk, 'j') != -1
    while 1
      let lnum = lnum + 1
      if lnum > line('$') || GetV(lnum, curVnum) =~# '\v^$|\s'
        let colLnum0 = lnum - 1 | break
      endif
    endwhile
  endif

  " get column start
  if stridx(a:jk, 'k') != -1
    let lnum = curLnum
    while 1
      let lnum = lnum - 1
      if lnum <= 0 || GetV(lnum, curVnum) =~# '\v^$|\s'
        let colLnum1 = lnum + 1 | break
      endif
    endwhile
  endif

  " visual select
  call cursor(colLnum0, col('.'))
  exec "normal! \<c-v>"
  call cursor(colLnum1, col('.'))
endfunction

vnoremap ic :<c-u>call SelectScreenColumn('v', 'j')<cr>
onoremap ic :call SelectScreenColumn('o', 'j')<cr>

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