如何在Vim中跳转到可视选择的开头或结尾?

81

有没有一种方法可以移动到可视选择的开头或结尾?

我知道在可视模式下使用 o 可以在两者之间切换,但我需要能够精确选择开头。

总体目标是用括号将一个可视选择区域括起来。


后续:

根据评论,我能够使用以下宏来实现这个目标。思路是:

  1. Esc 退出可视模式;
  2. `> 移动到上一个可视选择的末尾;
  3. a) 添加一个右括号;
  4. Esc 退出插入模式;
  5. `< 移动到上一个可视选择的开头;
  6. i( 插入一个左括号;
  7. Esc 再次退出插入模式。

例如:

map \q <ESC>`>a)<ESC>`<i(<ESC>

根据另一个评论,我们有一个更加简洁的解决方案:

map \q c()<ESC>P
5个回答

105

在当前缓冲区中,有两个相关的内置标记,它们保存了最后一个可视选择的第一个和最后一个字符的位置。 要将光标移动到这些标记处,请分别使用命令`<`>(请参见:help `>:help `<)。


4
这正是我所寻找的答案。@duckworthd - 你应该考虑点击接受 :-) - Grant McLean
但是如何保持选择不变呢? - Adrian
25
你的意思是在不离开 Visual 模式下进行切换吗?如果是,你可以使用 o 命令。 - ib.
1
我还是缺少我正在寻找的功能。我想将光标移动到选择的末尾而不改变它。如果光标在顶部,o可以实现这一点,但如果已经在底部,则需要保持不变。 '>会起作用,但会更改选择。 - rsoren
@rsoren: 你可以尝试这样做::vnoremap <leader>ve <esc>`<v`>。(对于选择的起始位置,相同的映射将是:vnoremap <leader>vb <esc>`>v`<。) - ib.
@rsoren:你可以尝试这样做::vnoremap <leader>ve <esc>`<v`>。(同样的映射,但是用于选择的起始位置可以是:vnoremap <leader>vb <esc>`>v`<。) - undefined

97

当你处于可视化选择状态时,点击o,它将更改光标位置到选择的另一端。 然后使用O跳回。


3
我认为只需按 o 键即可垂直跳转。如果您处于可视块选择模式,则按 O 键可以水平跳转。 - dosentmatter
1
只是为了澄清一下,在可视块选择模式下,o键会跳到光标最远的角落。而O键则会跳到同一行上最远的点(就像你所描述的那样)。这使得可以轻松访问块的所有4个角落。 - horta
@horta,是的,你说得对。o 更准确地描述为对角线移动,而不是垂直或水平移动。 - dosentmatter

26

“用最简单的方式将“选定的可见区域括在括号内”的方法是:

c修改可视选定区域为(),然后在中间放置它:c()<ESC>P

我建议在.vimrc文件中定义一个新的可视模式命令(例如,\q)来实现此功能:

:vmap \q c()<ESC>P

这种方法也适用于可视矩形区域(<C-V>):它会在每个块行周围放置 ()


1
接近了,但还不完美。如果在可视选择中的最后一个字符刚好是该行的最后一个字符,那么光标会停留在该可视选择之前的字符上方。因此,使用插入("i")会导致插入的带括号的文本比预期向左移动一个字符位置。 - duckworthd

19
如果你只想给一个视觉选区加上包围符号,那么已经有人做了这个工作,即由Tim Pope编写的这个插件称为surround。它可以用你喜欢的定界符将单词或视觉选择包围起来。
选择你的视觉选择比如 i like vim,敲击 S) 获得 (i like vim) 或者 S( 获得 ( i like vim ),要将其更改为 [i like vim],请键入 cs](更改环绕)并键入 ds] 以删除最后的 i like vim

12

如果您无法使用Surrond.vim,则可以使用以下方法:

  1. 使用vV进行视觉选择。
  2. 使用<Esc>退出选择。
  3. 键入`>a)<Esc>在选择的最后一个字符后插入右括号。
  4. 键入`<i(<Esc>在选择的第一个字符前插入左括号。

我觉得这个顺序很奇怪/有趣 - 也就是说,你必须先到达可视选择的结尾(\>)**先**插入字符,然后再回到选择的开头(`<)插入字符。反过来做不起作用,因为由于某种原因,一旦在可视选择的开头插入字符,vim现在认为可视选择的“结尾”在之前的一个字符之前。 - amy
@amy,确实是这个原因。 - romainl
这种情况确实有点奇怪,不是吗?我本以为 Vim 会以更智能的方式跟踪上一次可视选择的结束位置,以适应这种情况。实际上,它是根据当前行中的字符位置来定义 \>的。所以,如果它在第29个字符处,而你在该行前面插入了一个( 字符,那么现在字符29(`>` 指向的位置)实际上是在你认为它应该在的位置之前一个字符,也就是第30个字符。 - amy
这种情况很奇怪,不是吗?我本以为vim会以更智能的方式跟踪上一次可视选择的结尾,以适应这种情况。实际上,它定义了\>,基于当前行中的字符位置。因此,如果它是第29个字符,现在你在该行之前插入了一个(字符,那么字符29(`>`指向的位置)实际上是在你认为它应该在的位置之前一个字符,即第30个字符。 - amy
我不会说这很“奇怪”。更像是“稍微有些不直观”。但一旦你内化了标记的工作原理,它就变成了第二天性。问题实际上比那更普遍和抽象:如果你改变了先决条件,那么你的条件永远不会被满足。对于像列表中的项目或字符串中的字母这样的位置事物,从开头开始可能会导致这种情况,因此从结尾开始更安全。 - romainl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接