一千萬個為什麽

搜索

移動到列的第一個/最後一個非空白字符(“垂直W/B/E”)

例如移動(光標在粗體斜體字母上,在第二列中)

blablabla
blablabla
blablabla
blablabla
  bla
  bla
  bla
bLablabla
[email protected]

blablabla
blablabla
blablabla
blablabla
  bla
  bla
  bla
bLablabla
[email protected]

and then 至 the "@". That would be "vertical E". And the same for W (move from the initial position 至 the capital "L") and B (@ → L → first l).

最佳答案

有趣。字運動命令的垂直模擬。我不知道有任何本地方式這樣做,所以我的第一個想法是從正則表達式搜索開始。事實證明,在一個步驟中進行此類搜索並非易事,但仍然可行。

首先是幾個筆記:

  • To make it quite a bit easier I'm using (vertical) WORD motions (W,B,E) rather than word (w,b,e). The latter is [a-zA-Z0-9_]+ OR a sequence of other non-blank characters while a WORD is just \S+. In fact, your example is actually demonstrating WORD motion because otherwise the second e would end up on the L not the @. [Note: the question originally referred to w,b,e but has since been edited.]
  • The patterns will use 'very magic' flag to reduce length and improve readability.
  • To start, my pattern will be based on a fixed column number (4). This will be made variable later.

E 開始......

\v%4v\S.*(\n.{3}\s|\n.{,3}\n|%$)
  • \v - very magic
  • %4v\S - in column 4 there must be a non-whitespace character (our WORD char)
  • .* - slurp up anything remaining on the line
  • (..|..|..) - parens indicating any of the following three patterns are allowed on the next line...
  • \n.{3}\s - after the current line's newline the next line starts with three characters followed by whitespace (in the cursor column)
  • \n.{,3}\n - after the newline there are three or fewer characters total on the next line
  • %$ - there is no next line as indicated by this end of file token (allowing vertical E motion to end on the last line of the buffer)

作為獨立模式,這對我們沒有多大幫助。最好的辦法是把它放在一個函數中。關鍵線看起來像:

let curcol = getcurpos()[2]
let prevcol = curcol - 1
call searchpos('\v%' . curcol . 'v\S.*\n(.{' . prevcol . '}\s|.{,' . prevcol . '}\n)')

這只是查看光標當前所在的任何列,並將其插入前面討論過的模式中。

將上述模式和類似模式組合用於其他運動並通過運動類型 WBE 進行參數化我得到:

func! VertWordMotion(motion)
    let curcol = getcurpos()[2]
    let prevcol = curcol - 1
    if a:motion == 'E'
        call searchpos('\v%' . curcol . 'v\S.*(\n.{' . prevcol . '}\s|\n.{,' . prevcol . '}\n|%$)', 'W')
    elseif a:motion == 'B'
        call searchpos('\v(%' . curcol . 'v\s.*\n|^.{,' . prevcol . '}\n|%^).{' . prevcol . '}\zs\S', 'bW')
    elseif a:motion == 'W'
        call searchpos('\v(%' . curcol . 'v\s.*|^.{,' . prevcol . '})\n.{' . prevcol . '}\zs\S', 'W')
    else
        echohl ErrorMsg | echo 'Not a valid motion: ' . a:motion | echohl None
    endif
endfunc

最後,創建這樣的映射:

nnoremap E :call VertWordMotion('E')
nnoremap B :call VertWordMotion('B')
nnoremap W :call VertWordMotion('W')

轉載註明原文: 移動到列的第一個/最後一個非空白字符(“垂直W/B/E”)