Vim:转到可视区域的开头或结尾

Bog*_*iev 6 vim hotkeys keymap

我想做一些棘手的映射,用一些代码包装当前选定的可视区域。为了做到这一点,我需要确保我位于当前视觉区域的开头。在视觉模式下是否有任何热键?

Chr*_*sen 8

如果我理解正确,您也许可以使用

`<
Run Code Online (Sandbox Code Playgroud)

`>
Run Code Online (Sandbox Code Playgroud)

棘手的一点是它们会转到前一个视觉区域的开始/结束,而不是当前的。

所以,你可以做这样的事情:

:vmap __ <Esc>`>aEND<Esc>`<iSTART<Esc>l
Run Code Online (Sandbox Code Playgroud)

在我的 Vim 版本中,使用该序列后,最后一个视觉区域有点不稳定(重新选择它会gv选择一个不太正确的区域)。

要在当前可视区域中移动,用户可以交互使用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
Run Code Online (Sandbox Code Playgroud)