移动

不管是插入或者删除字符,都需要将光标移动到合适的位置。Vim 有一大堆命令可以移动光标。本章只介绍最基本、最常用的一些命令。

单词移动

w 命令将光标移动到前一个单词的词首; b 命令向后移动一个单词。 用图表示如下:

This is a line with example text ~
--->-->->----------------->
 w  w  w    3w

This is a line with example text
<----<--<-<---------<---
   b   b b    2b      b

还有一个 e 命令可以移到下一个单词的词末,而 ge 则移动到前一个单词的末尾:

This is a line with example text
   <-   <--- ----->   ---->
   ge    ge     e       e

注解

如果单词位于一行中的末尾, w 命令将光标带到下一行的词首,这样就可以在一个段落中移动。 b 命令在反方向完成移动。

在某些文件中,在用空白字符分隔的 “字串” 之间移动会更有效率,这些 “字串” 并不是通常意义上的 “单词”。大写字母 WB 命令,来移动光标。所有移动命令的区别如下图所示:

       ge      b          w                             e
       <-     <-         --->                          --->
This is-a line, with special/separated/words (and some more).
   <----- <-----         -------------------->         ----->
     gE      B                   W                       E
       ge      b          w                             e

组合运用这些大写和小写的命令,你可以在段落内快速前后移动。

括号匹配

在写程序的时候,经常会遇到嵌套的 () 结构。 % 命令能匹配成对符号(例如:()、[]、{} 等,用 'matchpairs' 选项定义),并在它们之间跳转。

            %
         <----->
if (a == (b * c) / d)
   <---------------->
            %

当光标不在一个可用的字符上, % 会先正向查找找到一个。比如光标停留在上例中的行首, % 会正向查找到第一个 ( 。

移动到指定字符

单字符查找命令是最有用的移动命令之一。 fx 命令向前查找本行中的第一个 x 字符;而 Fx 命令向后查找本行中的第一个 x 字符

                  Fh
          <----------------
To err is human.  To really foul up you need a computer.
---------->--------------->
    fh           fy
           --------------------->
                      3fl

这两个命令可以通过 ; 命令重复, , 命令则用于反向重复。无论用哪个命令,光标永远不会移出当前行。

移动到行首或行尾

$ 命令将光标移动到当前行行尾。如果键盘上有 <End> 键也可以完成相同的功能;而数字 0 命令将光标移动到当前行行首,<Home> 键可以完成相同的功能。 ^ 命令将光标移动到当前行的第一个非空字符,图示如下:

            ^
     <------------
.....This is a line with example text
<-----------------   --------------->
     0                  $

(这里 "....." 表示空白字符)

注解

像大多数移动命令一样, $ 命令接受计数前缀。但“移动到当前行的行尾 n 次”没有意义,所以它会使光标移动到另一行。例如, 1$ 将光标移动到当前行的行尾,而 2$ 则移动到下一行的行尾,如此类推。

0 命令不能加计数前缀,因为 0 本身就是个数字。而且, ^ 命令使用计数前缀没有任何效果。

移动到指定行

G 命令将光标移动到文件的最后一行的行首。将这个命令加上一个计数前缀,可以将光标移动到指定行的行首。例如, 33G 将光标移动到第 33 行的行首。

gg 命令将光标移动到文件第一行的行首, 1G 也可以完成这个功能,但稍显复杂。

    |   first line of a file   ↑
    |   text text text text    |
    |   text text text text    |  gg
7G  |   text text text text    |
    |   text text text text
    |   text text text text
    ↓  text text text text     |
        text text text text    |  G
        text text text text    |
        last line of a file    ↓

另一个定位行的方法是使用带计数前缀的 % 命令。例如, 50% 移动到文件的中间,而 90% 移动到差不多结尾的位置。

前面的描述假定你想移动到文件中的某一行,而不在乎它是否可见。那么如何在屏幕显示的所有内容行中移动呢?下图演示了三个可以使用的命令:

        +---------------------------+
H -->   | text sample text          |
        | sample text               |
        | text sample text          |
        | sample text               |
M -->   | text sample text          |
        | sample text               |
        | text sample text          |
        | sample text               |
L -->   | text sample text          |
        +---------------------------+

提示: H 表示 "Home"(头), M 表示 "Middle"(中),而 L 表示 "Last"(尾)。

滚屏

CTRL-U 命令向下滚动半屏。 CTRL-D 命令把视窗向下移动半屏,所以把文字向上移动半屏。

向下滚动一整屏(减去两行)的命令是 CTRL-F (forward 向前)。反向滚动的命令是 CTRL-B (backward 向后)。

                               +----------------+
                               | some text      |
                               | some text      |
                               | some text      |
+---------------+              | some text      |
| some text     |  CTRL-U  --> |                |
|               |              | 123456         |
| 123456        |              +----------------+
| 7890          |
|               |              +----------------+
| example       |  CTRL-D -->  | 7890           |
+---------------+              |                |
                               | example        |
                               | example        |
                               | example        |
                               | example        |
                               +----------------+

使用标记

10G 命令将光标从第三行跳转到第十行时,Vim 会记住第三行的位置,这个位置成为一个标记,要回到原来的地方,使用 `` 命令。 ` 也可以替换为单引号 '

注解

一般情况下,每次执行一个将光标移出本行的命令时,该移动即被称为一个“跳转”。其中也包括查找命令中的 n,但不包括 fxtx 这些行内查找命令或者 we 等词移动命令。

另外 jk 不会被当做是一次 "跳转",即使在前面加上计数前缀也不例外。

`` 命令可以在两个位置上跳来跳去。而 CTRL-O 命令则会跳到一个“较老”的地方(O 表示 older)。CTRL-I 则跳到一个“较新”的地方(I 在键盘上紧靠着 O)。考虑如下命令序列:

gg
33G
/^The
CTRL-O

首先跳到文件行首,然后跳到第 33 行,紧接着查找以 The 开头的一行。用 CTRL-O 命令会跳回到 33 行,再执行 CTRL-O 会跳到文件行首。用 CTRL-I 会再次跳到 33 行。再用一次 CTRL-I 会到达找到 The 的地方。 CTRL-I 的功能与 <Tab> 一样。

      |  example text   ↑             |
33G   |  example text   |  CTRL-O     | CTRL-I
      |  example text   |             |
      ↓  line 33 text   ↑             ↓
      |  example text   |             |
/^The |  example text   |  CTRL-O     | CTRL-I
      ↓  There you are  |             ↓
         example text

可以用如下命令输出一个可以跳转位置的列表,最后一个使用的标记会用 > 符号标记。

:jumps

有名字的标记

Vim 允许你在文本中放置自定义的标记。命令 ma 用 a 标记当前的光标位置。你可以在文本中使用 26 个标记(a~z)。需要注意的是这些标记是不可见的。

要跳到一个你定义的标记,可以使用命令 `{mark} ,这里 {mark} 是指定义标记的那个字母。所以, `a 命令会移动到标记 a 的位置。

注解

'{mark} 命令会移动到标记所在行的行首。这与 `{mark} 命令是不同,后者会移动到标记时光标所在的具体位置。

可以用如下命令取得所有的标记的列表,注意是标记列表,而不是“跳转”列表:

:marks

你会注意到有一些特殊的标记,包括:

  • ' 跳转前的光标位置
  • " 最后编辑的光标位置
  • [ 最后修改的开始位置
  • ] 最后修改的结束位置