web-dev-qa-db-ja.com

Vim:視覚野の最初または最後に移動します

現在選択されている視覚野をコードでラップするトリッキーなマッピングを行いたいと思います。そのためには、現在の視覚野の先頭にいることを確認する必要があります。ビジュアルモードでそのためのホットキーはありますか?

3
Bogdan Gusiev

私が正しく理解していれば、あなたは使うことができるかもしれません

`<

そして

`>

トリッキーな点は、現在の領域ではなく、前の視覚領域の開始/終了に移動することです。

したがって、次のようなことができます。

:vmap __ <Esc>`>aEND<Esc>`<iSTART<Esc>l

私のバージョンのVimでは、そのシーケンスを使用した後、最後の視覚領域が少し不安定になります(gvで再選択すると、正しくない領域が選択されます)。

current視覚野内を移動するには、ユーザーはo(ブロック領域を使用している場合はO)をインタラクティブに使用できますが、必要に応じてこれらは決定論的ではありません。マップでそれらを使用します。

そこで、oの決定論的バージョン(以下では_^および_$として定義)を作成するために、以下の関数を作成しました。例の_*コマンドは、それらを使用して上記の__と同様の「ラッピング」を実行しますが、ラッピングを実行した後に領域(1v)を再選択することにより、視覚野を選択したままにする偽物も使用します。

:function! MoveToVisualAreaExtrema(wantEnd) range
:  normal gv
:  let l:mode = mode()
:  " only character (v) and line mode (V) work with this implementation
:  if !(l:mode == 'v' || l:mode == 'V')
:    throw 'must be in character- or line-visual mode'
:  endif
:  " get original posision
:  let l:iLn = line('.')
:  let l:iCl = col('.')
:  " move to other end of visual selection
:  normal o
:  " get current position
:  let l:cLn = line('.')
:  let l:cCl = col('.')
:  let l:atEnd = (l:cLn > l:iLn) || (l:cLn == l:iLn) && (l:cCl > l:iCl)
:  if a:wantEnd != l:atEnd
:    normal o
:  endif
:  if l:mode == 'V'
:    execute 'normal ' . (a:wantEnd ? '$' : '0')
:  endif
:endfunction
:vmap _^ :call MoveToVisualAreaExtrema(0)<CR>
:vmap _$ :call MoveToVisualAreaExtrema(1)<CR>

:" Example: wrap ";print q();" around the visual region
:vmap _* _$<Esc>a);<Esc>gv_^<Esc>i;print q(<Esc>l1v
4
Chris Johnsen

大文字のH(「ホーム」)で最初に移動し、「L」(「最後」)で最後に移動します。

問題を引き起こす可能性のある動作の1つは、カーソルが行の最初の非空白文字に置かれることです。したがって、「0」と入力して、行の絶対的な先頭に移動します。

0
Peter Westlake