Vim documentation: usr_10

*usr_10.txt* For Vim version 7.4 最近更新: 2006年12月 Vim 用户手册 - by Bram Moolenaar 译者: Nek_in http://vimcdoc.sf.net 做大修改 第四章我们已经介绍过作小修改的方法了。本章开始介绍如何重复多次修改和如何改动大 量的文字。这将包括使用可视模式处理一些文本块,还有使用一个外部程序去完成非常复 杂的功能。 |10.1| 记录与回放命令 |10.2| 替换 |10.3| 命令范围 |10.4| global 命令 |10.5| 可视列块模式 |10.6| 读、写部分文件内容 |10.7| 排版文本 |10.8| 改变大小写 |10.9| 使用外部程序 下一章: |usr_11.txt| 从崩溃中恢复 前一章: |usr_09.txt| 使用 GUI 版本 目录: |usr_toc.txt|

*10.1* 记录与回放命令 "." 命令重复前一个修改操作。但如果你需要作一些更复杂的操作它就不行了。这时,记 录命令就变得很有效。这需要三个步骤: 1. "q{register}" 命令启动一次击键记录,结果保存到 {register} 指定的寄存器中。 寄存器名可以用 a 到 z 中任一个字母表示。 2. 输入你的命令。 3. 键入 q (后面不用跟任何字符) 命令结束记录。 现在,你可以用 "@{register}" 命令执行这个宏。 现在看看你可以怎么用这些命令。假设你有如下文件名列表: stdio.h ~ fcntl.h ~ unistd.h ~ stdlib.h ~ 而你想把它变成这样: #include "stdio.h" ~ #include "fcntl.h" ~ #include "unistd.h" ~ #include "stdlib.h" ~ 先移动到第一行,接着执行如下命令: qa 启动记录,并使用寄存器 a ^ 移到行首 i#include "<Esc> 在行首输入 #include " $ 移到行末 a"<Esc> 在行末加上双引号 (") j 移到下一行 q 结束记录 现在,你已经完成一次复杂的修改了。你可以通过重复三次 "@a" 完成余下的修改。 "@a" 命令可以通过计数前缀修饰,使操作重复指定的次数。在本例中,你可以输入: 3@a 移 动 并 执 行 你可能有多个地方需要修改。只要把光标移动到相应的位置并输入 "@a" 命令即可。如果 你已经执行过一次,你可以用 "@@" 完成这个操作,这更容易输入一些。例如,你上次使 用 "@b" 命令引用了寄存器 b,下一个 "@@" 命令将使用寄存器 b。 如果你对回放命令和 "." 命令作一个比较,你会发现几个区别。首先,"." 只能重 复一次改动。而在上例中,"@a" 可以重复多次改动,还能够执行移动操作。第二, "." 只能记住最后一次变更操作。而寄存器执行命令允许你记录任何操作并使用象 "@a" 这样 的命令回放这些被记录的操作。最后,你可以使用 26 个寄存器,因此,你可以记录多达 26 个命令序列。 使 用 寄 存 器 用来记录操作的寄存器与你用来拷贝文本的寄存器是相同的。这允许你混合记录操作和其 它命令来操作这些寄存器。 假设你在寄存器 n 中记录了一些命令。当你通过 "@n" 执行这些命令时,你发现这 些命令有些问题。这时你可以重新录一次,但这样你可能还会犯其它错误。其实,你可以 使用如下窍门: G 移到行尾 o<Esc> 建立一个空行 "np 拷贝 n 寄存器中的文本,你的命令将被拷到整个文 件的结尾 {edits} 象修改普通文本一样修改这些命令 0 回到行首 "ny$ 把正确的命令拷贝回 n 寄存器 dd 删除临时行 现在你可以通过 "@n" 命令执行正确的命令序列了。(如果你记录的命令包括换行符,请 调整上面例子中最后两行的操作来包括所有的行。) 追 加 寄 存 器 到此为止,我们一直使用小写的寄存器名。要附加命令到一个寄存器中,可以使用大写的 寄存器名。 假设你在寄存器 c 中已经记录了一个修改一个单词的命令。它可以正常工作,但现 在你需要附加一个搜索命令以便找到下一个单词来修改。这可以通过如下命令来完成: qC/word<Enter>q 启动 "qC" 命令可以对 c 寄存器追加记录。由此可见,记录到一个大写寄存器表示附加 命令到对应的小写寄存器。 这种方法在宏记录,拷贝和删除命令中都有效。例如,你需要把选择一些行到一个寄存器 中,可以先这样拷贝第一行: "aY 然后移到下一个要拷贝的地方,执行: "AY 如此类推。这样在寄存器 a 中就会包括所有你要拷贝的所有行。

*10.2* 替换 *find-replace* ":substitute" 命令使你可以在连续的行中执行字符串替换。下面是这个命令的一般形 式: :[range]substitute/from/to/[flags] 这个命令把 [range] 指定范围中的字符串 "from" 修改为字符串 "to"。例如,你可以把 连续几行中的 "Professor" 改为 "Teacher",方法是: :%substitute/Professor/Teacher/ 备注: 很少人会把整个 ":substitute" 命令完整敲下来。通常,使用命令的缩写形式 ":s" 就行了。下文我们将使用这个缩写形式。 命令前面的 "%" 表示命令作用于全部行。如果不指定行范围,":s" 命令只作用在当前行 上。|10.3| 将对 "行范围" 作深入的介绍。 默认情况下,":substitute" 命令只对某一行中的第一个匹配点起作用。例如,前面例子 中会把行: Professor Smith criticized Professor Johnson today. ~ 修改成: Teacher Smith criticized Professor Johnson today. ~ 要对行中所有匹配点起作用,你需要加一个 g (global,全局) 标记。下面命令: :%s/Professor/Teacher/g 对上面例子中的句子的作用效果如下: Teacher Smith criticized Teacher Johnson today. ~ ":s" 命令还支持其它一些标志位,包括 "p" (print,打印),用于在命令执行的时候打 印出最后一个被修改的行。还有 "c" (confirm,确认) 标记会在每次替换前向你询问是 否需要替换。执行如下命令: :%s/Professor/Teacher/c Vim 找到第一个匹配点的时候会向你提示如下: replace with Teacher (y/n/a/q/l/^E/^Y)? (中文翻译如下: 替换为 Teacher 么 (y/n/a/q/l/^E/^Y)? ) 这种时候,你可以输入如下回答中的一个: y Yes,是;执行替换 n No,否;跳过 a All,全部;对剩下的匹配点全部执行替换,不需要再确认 q Quit,退出;不再执行任何替换 l Last,最后;替换完当前匹配点后退出 CTRL-E 向上滚动一行 CTRL-Y 向下滚动一行 ":s" 命令中的 "from" 部分实际上是一个 "匹配模式" (还记得吗?这是我们前面给 pattern 起的名字译者),这与查找命令一样。例如, 要替换行首的 "the" 可以这样 写: :s/^the/these/ 如果你要在 "from" 或者 "to" 中使用正斜杠,你需要在前面加上一个反斜杠。更简单的 方法是用加号代替正斜杠。例如: :s+one/two+one or two+

*10.3* 命令范围 ":substitute" 命令和很多其它的 ":" 命令一样,可以作用于选中的一些行。这称为一 个 "范围"。 最简单的范围表达形式是 "{number},{number}"。例如: :1,5s/this/that/g 这会在 1 到 5 行上执行替换命令。(包括第 5 行)。"范围" 总是放在一个命令的前面。 如果只用一个数值,表示某个指定的行: :54s/President/Fool/ 有些命令在不指定范围的时候作用于整个文件。要让它只作用于当前行可以用当前行范围 标识 "."。":write" 命令就是这样: 不指定范围的时候,它写入整个文件,如果要仅写 入当前行,可以这样: :.write otherfile 文件的第一行行号总是 1,最后一行又是多少呢?"$" 字符用于解决这个问题。例如,要 修改当前行到文件末的全部内容,可以这样: :.,$s/yes/no/ 我们前面使用的 "%" 就是 "1,$" 的缩写形式,表示从文件首到文件末。 在 范 围 中 使 用 模 式 假设你正在编辑一本书中的一章,并且想把所有的 "grey" 修改成 "gray"。但你只想修 改这一章,不想影响其它的章节。另外,你知道每章的开头的标志是行首的单词为 "Chapter"。下面的命令会对你有帮助: :?^Chapter?,/^Chapter/s=grey=gray=g 你可以看到这里使用了两个查找命令。第一个是 "?^Chapter?",用于查找前一个行首的 "Chapter",就是说 "?pattern?" 用于向前查找。同样,"/^Chapter/" 用于向后查找下 一章。 为了避免斜杠使用的混淆,在这种情况下,"=" 字符用于代替斜杠。使用斜杠或使用 其它字符其实也是可以的。 加 减 号 上面的方案其实还是有问题的: 如果下一章的标题行中包括 "grey",这个 "grey" 也会 被替换掉。如果你正好想这样就最好,可是正好你不想呢?这个时候你需要指定一个偏 移。 要查找一个模式,并且使用它的前一行,需要这样: /Chapter/-1 你可以用任意数值代替命令中的 1。要定位匹配点下的第二行,要这样: /Chapter/+2 偏移还可以用于其它范围指定符。看一下下面这个例子: :.+3,$-5 这指定当前行下面第三行到文件末倒数第五行的范围。 使 用 标 记 除了指定行号,(这需要记住并把它敲出来),你还可以使用标记。 在前面的例子中,你可以用标记指出第三章的位置。例如,用 "mt" 标记开头,再用 "mb" 标记结尾。然后你就可以用标记表示一个范围 (包括标记的那一行): :'t,'b 可 视 模 式 和 范 围 你可以在可视模式中选中一些行。如果你现在输入 ":" 启动冒号命令模式,你会看到: :'<,'> 现在,你可以输入剩下的命令,这个命令的作用范围就是可视模式中指定的范围。 备注: 如果使用可视模式选中行的一部分,或者用 CTRL-V 选中一个文本列块,然后执 行冒号命令,命令仍作用于整行,而不只是选中的范围。这可能会在以后的版本 中修正。 '< 和 '> 实际上是标记,分别标识可视模式的开始和结尾。这个标记一直有效,直到选 中了其它的范围为止。你还可以用标记跳转命令 "'<" 跳转到选中文本的开始处。你还可 以把这个标记和其它标记混合,例如: :'>,$ 这表示从选中部分的结尾到文件末。 指 定 行 数 如果你知道要修改多少行,你可以先输入一个数值再输入冒号。例如,如果你输入 "5:",你会得到: :.,.+4 现在你可以继续你的命令,这个命令将作用于当前行及其后 4 行。

*10.4* global 命令 ":global" 命令是 Vim 中一个更强大的命令 (之一)。它允许你找到一个匹配点并且在那 里执行一个命令。它的一般形式是: :[range]global/{pattern}/{command} 这有点象 ":substitute" 命令。只是它不替换文本,而是执行 {command} 指定的命令。 备注: global 中执行的命令只能是冒号命令。普通模式命令不能在这里使用。如果需 要,可以使用 |:normal| 命令。 假设你要把 "foobar" 修改为 "barfoo",但只需要修改 C++ 风格的注释中的内容。这种 注释以 "//" 开头。所以可以使用如下命令: :g+//+s/foobar/barfoo/g 这个命令用 ":g" 开头,这是 ":global" 的缩写形式,就像 ":s" 是 ":substitute" 的 缩写形式一样。然后是一个匹配模式,由于模式中包括正斜杠,我们用加号作分隔符,后 面是一个把 "foobar" 替换成 "barfoo" 的替换命令。 全局命令的默认范围是整个文件,所以这个例子中没有指定范围。这一点与 ":substitute" 是不同的。后者只作用于一行。 这个命令并非完美。因为 "//" 可能出现在一行的中间,但替换命令会把前后的匹配 点都替换了。 像 ":substitute" 一样,这里也可以使用各种各样的匹配模式。当你从后面的章节中学 会更多的关于模式的知识,它们都可以用在这里。

*10.5* 可视列块模式 CTRL-V 命令可以选中一个矩形文本块。有几个命令是专门用来处理这个文本块的。 在可视列块模式中,"$" 命令有些特别。当最后一个移动命令是 "$" 时,整个可视列块 将被扩展到每一行的行尾。这种状态在你使用垂直移动命令的时候一直被保持,直到你使 用水平移动命令为止。就是说,用 "j" 命令会保持这种状态,而 "h" 会退出。 插 入 文 本 "I{string}<Esc>" 命令把 {string} 插到可视列块的每一行的左边。你用 CTRL-V 进入 可视列块模式,然后移动光标定义一个列块。接着输入 I 进入插入模式,并随后输入文 本。这时,你输入的内容只出现在第一行。 然后你输入 <Esc> 结束输入,刚才输入的字符串将神奇地出现在每一行的可视区的 左边。例如: include one ~ include two ~ include three ~ include four ~ 把光标移到第一行 "one" 的 "o"上,输入 CTRL-V。然后用 "3j" 向下移动到 "four"。 现在你选中了四行的一个方块。接着输入: Imain.<Esc> 结果将是: include main.one ~ include main.two ~ include main.three ~ include main.four ~ 如果选中的块经过一个短行,并且这行没有任何内容包括在可视列块中,则新的文本不会 被插入到该行中。例如,对于下面的例子,用可视列块选中第一和第三行的 "long",这 样第二行的文本将不会被包括在可视列块中: This is a long line ~ short ~ Any other long line ~ ^^^^ 用可视列块选中的部分 现在输入 "Ivery <esc>"。结果将是: This is a very long line ~ short ~ Any other very long line ~ 可以注意到,第二行中没有插入任何文本。 如果插入的文本中包括一个新行,则 "I" 命令的效果与普通插入语句一样,只影响块的 第一行。 "A" 命令的效果与 "I" 命令一样,只是把文字插入可视列块的右边,而且在短行中会插 入文字。这样,你有在短行中插入文字与否的不同选择。 "A" 在如下情况会有一些特别: 选中一个可视列块然后用 "$" 命令使可视列块扩展 到行尾。然后用 "A" 命令插入文本,文件将被插入到 "每一行" 的行尾。 还是用上面的例子,在选中可视列块后输入 "$A XXX<Esc>",结果将是: This is a long line XXX ~ short XXX ~ Any other long line XXX ~ 出现这个效果完全是 "$" 命令的作用,Vim 能记住这个命令,如果你用移动命令选中相 同的可视列块,是不会有这样的效果的。 修 改 文 本 可视列块中的 "c" 命令会删除整个可视列块并转入 "插入" 模式,使你可以开始文本, 这些文本会被插入可视列块经过的每一行。 在上面的例子中,如果仍选中包括所有 "long" 的一个可视列块,然后输入 "c_LONG_<Esc>",结果会变成: This is a _LONG_ line ~ short ~ Any other _LONG_ line ~ 与 "I" 命令一样,短行不会发生变化。而且在插入的过程中,你不能断行。 "C" 命令从块的左边界开始删除所有行的后半段,然后状态切换到 "插入" 模式让你输 入文本。新的文本被插入到每一行的末尾。 在上面的例子中,如果命令改为 "Cnew text<Esc>",你将获得这样的结果: This is a new text ~ short ~ Any other new text ~ 可以注意到,尽管只有 "long" 被选中,它后面的内容也被删除了。所以在这种情况下, 块的左边界才是有意义的。 同样,没有包括在块中的行不会受影响。 还有一些命令只影响被选中的字符: ~ 交换大小写 (a -> A 而 A -> a) U 转换成大写 (a -> A 而 A -> A) u 转换成小写 (a -> a 而 A -> a) 以 一 个 字 符 填 充 要以某一个字符完全填充整个块,可以使用 "r" 命令。再次选中上例中的文本,然后键 入 "rx": This is a xxxx line ~ short ~ Any other xxxx line ~ 备注: 如果你要在可视列块中包括行尾之后的字符,请参考 25 章的 'virtualedit' 特性。 平 移 ">" 命令把选中的文档向右移动一个 "平移单位",中间用空白填充。平移的起始点是可 视列块的左边界。 还是用上面的例子,">" 命令会导致如下结果: This is a long line ~ short ~ Any other long line ~ 平移的距离由 'shiftwidth' 选项定义。例如,要每次平移 4 个空格,可以用这个命 令: :set shiftwidth=4 "<" 命令向左移动一个 "平移单位",但能移动的距离是有限的,因为它左边的不是空白 字符的字符会挡住它,这时它移到尽头就不再移动。 连 接 若 干 行 "J" 命令连接被选中的行。其实就是删除所有的换行符。其实不只是换行符,行前后的多 余空白字符会一起被删除而全部用一个空格取代。如果行尾刚好是句尾,就插入两个空格 (参见 'joinspaces' 选项) 还是用那个我们已经非常熟悉的例子,这回的结果将是: This is a long line short Any other long line ~ "J" 命令其实不关心选中了哪些字符,只关心块涉及到哪些行。所以可视列块的效果与 "v" 和 "V" 的效果是完全一样的。 如果你不想改变那些空白字符,可以使用 "gJ" 命令。

*10.6* 读、写文件的一部分 当你在写一封 e-mail,你可能想包括另一个文件。这可以通过 ":read {filename}" 命 令达到目的。这些文本将被插入到光标的下面。 我们用下面的文本作试验: Hi John, ~ Here is the diff that fixes the bug: ~ Bye, Pierre. ~ 把光标移到第二行然后输入: :read patch 名叫 "patch" 的文件将被插入,成为下面这个样子: Hi John, ~ Here is the diff that fixes the bug: ~ 2c2 ~ < for (i = 0; i <= length; ++i) ~ --- ~ > for (i = 0; i < length; ++i) ~ Bye, Pierre. ~ ":read" 支持范围前缀。文件将被插入到范围指定的最后一行的下面。所以 ":$r patch" 会把 "patch" 文件插入到当前文件的最后。 如果要插入到文件的最前面怎么办?你可以把文本插入到第 0 行,这一行实际上是 不存在的。在普通的命令的范围中如果你用这个行号会出错,但在 "read" 命令中就可 以: :0read patch 这个命令把 "patch" 文件插入到全文的最前面。 保 存 部 分 行 要把一部分行写入到文件,可以使用 ":write" 命令。在没有指定范围的时候它写入全 文,而指定范围的时候它只写入范围指定的行: :.,$write tempo 这个命令写入当前位置到文件末的全部行到文件 "tempo" 中。如果这个文件已经存在, 你会被提示错误。Vim 不会让你直接写入到一个已存在的文件。如果你知道你在干什么而 且确实想这样做,就加一个叹号: :.,$write! tempo 小 心: "!" 必须紧跟着 ":write",中间不能留有空格。否则这将变成一个过滤器命令, 这种命令我们在本章的后面会介绍。 添 加 内 容 到 文 件 中 本章开始的时候介绍了怎样把文本添加到寄存器中。你可以对文件作同样的操作。例如, 把当前行写入文件: :.write collection 然后移到下一个位置,输入: :.write >>collection ">>" 通知 Vim 把内容添加到文件 "collection" 的后面。你可以重复这个操作,直到获 得全部你需要收集的文本。

*10.7* 排版文本 在你输入纯文本时,自动换行自然会是比较吸引的功能。要实现这个功能,可以设置 'textwidth' 选项: :set textwidth=72 你可能还记得在示例 vimrc 文件中,这个命令被用于所有的文本文件。所以如果你使用 的是那个配置文件,实际上你已经设置这个选项了。检查一下该选项的值: :set textwidth 现在每行达到 72 个字符就会自动换行。但如果你只是在行中间输入或者删除一些东西, 这个功能就无效了。Vim 不会自动排版这些文本。 要让 Vim 排版当前的段落: gqap 这个命令用 "gq" 开始,作为操作符,然后跟着 "ap",作为文本对象,该对象表示 "一 段" (a paragraph)。"一段" 与下一段的分割符是一个空行。 备注: 只包括空白字符的空白行不能分割 "一段"。这很不容易分辨。 除了用 "ap",你还可以使用其它 "动作" 或者 "文本对象"。如果你的段落分割正确,你 可以用下面命令排版整个文档: gggqG "gg" 跳转到第一行,"gq" 是排版操作符,而 "G" 是跳转到文尾的 "动作" 命令。 如果你没有清楚地区分段落。你可以只排版你手动选中的行。先移到你要格式化的行,执 行 "gqj"。这会排版当前行和下面一行。如果当前行太短,下面一行会补上来,否则多余 的部分会移到下面一行。现在你可以用 "." 命令重复这个操作,直到排版完所有的文 本。

*10.8* 改变大小写 你手头有一个分节标题全部是小写的。你想把全部 "section" 改成大写的。这可以用 "gU" 操作符。先在第一列执行: gUw < section header ----> SECTION header "gu" 的作用正好相反: guw < SECTION header ----> section header 你还可以用 "g~" 来交换大小写。所有这些命令都是操作符,所以它们可以用于 "动作" 命令,文本对象和可视模式。 要让一个操作符作用于当前行,可以执行这个操作符两次。例如,"d" 是删除操作 符,所以删除一行就是 "dd"。相似地,"gugu" 使整一行变成小写。这可以缩成 "guu"。 "gUgU" 可以缩成 "gUU" 而 "g~g~" 则是 "g~~"。例如: g~~ < Some GIRLS have Fun ----> sOME girls HAVE fUN ~

*10.9* 使用外部程序 Vim 有一套功能非常强大的命令,可以完成所有功能。但有些东西外部命令能够完成得更 好或者更快。 命令 "!{motion}{program}" 用一个外部程序对一个文本块进行过滤。换句话说,它 用一个文本块作为输入,执行一个由 {program} 指定的外部命令,然后用该程序的输出 替代选中的文本块。 如果你不熟悉 UNIX 的过滤程序,上面的描述可以说是比较糟糕的。我们这里举个例 子来说明一下。sort 命令能对一个文件排序。如果你执行下面的命令,未排序的文件 input.txt 会被排序并写入 output.txt。(这在 UNIX 和 Microsoft Windows 上都有效) sort <input.txt >output.txt 现在在 Vim 中完成相同的功能。假设你要对 1 到 5 行排序。你可以先把光标定位在第 一行,然后你执行下面的命令: !5G "!" 告诉 Vim 你正在执行一个过滤操作。然后 Vim 编辑器等待一个 "动作" 命令来告诉 它要过滤哪部分文本。"5G" 命令告诉 Vim 移到第 5 行。于是,Vim 知道要处理的是第 1 行 (当前行) 到第 5 行间的内容。 由于在执行一个过滤命令,光标被 Vim 移到了屏幕的底部,并显示一个 "!" 作提示 符。现在你可以输入过滤程序的名字,在本例中就是 "sort" 了。因此,你整个命令将 是: !5Gsort<Enter> 这个命令的结果是 sort 程序用前 5 行作为输入执行,程序的输出替换了原来的 5 行。 line 55 line 11 line 33 line 22 line 11 --> line 33 line 22 line 44 line 44 line 55 last line last line "!!" 命令用于对当前行执行过滤命令。在 Unix 上,"date" 命令能打印当前的时间和日 期,所以,"!!date<Enter>" 用 "date" 的输出代替当前行。这在为文件加入时间戳的时 候非常有用。 如 果 命 令 不 执 行 怎 么 办 启动一个 shell,发送一个命令并捕获它的输出,这需要 Vim 知道这个 shell 程序是怎 么工作的。如果你要使用过滤程序,你最好需要检查一下下面的选项: 'shell' 指定 Vim 用于执行外部命令的 shell。 'shellcmdflag' 传给 shell 的参数 'shellquote' shell 程序使用的引号 (用于引用命令) 'shellxquote' 用于命令和重定向文件名的引号 'shelltype' shell 程序的类型 (仅用于 Amiga) 'shellslash' 在命令中使用正斜杠 (仅用于 MS-Windows 和相容系统) 'shellredir' 用于把命令输出写入文件所使用的字符串 在 Unix 上,这几乎不是问题。因为总共只有两种 shell 程序: "sh" 类的和 "csh" 类 的。Vim 会检查选项 'shell',并根据它的类型自动设置这些参数。 但在 MS-Windows 上,有很多不同的 shell 程序,所以你必须修改这些 shell 程序 以便过滤功能正常执行。详细情况请参考相应选项的帮助。 读 入 一 个 命 令 的 输 出 要把当前目录的内容读进文件,可以用如下命令: Unix 上: :read !ls MS-Windows 上: :read !dir "ls" 或者 "dir" 的输出会被捕获并插入到光标下面。这好像读入一个文件一样,但是需 要加上一个 "!" 让 Vim 知道后面是一个命令。 这些命令还可以带参数。而且前面还可以带一个范围用于告诉 Vim 把这行放在什么 地方: :0read !date -u 这将用 UTC 格式把当前的时间插入到文件开头。(当然了,你的 date 命令必须能够接受 -u 选项。) 注意 这与 "!!date" 的区别: "!!date" 替代一行,而 ":read !date" 插入 一行。 把 文 本 输 出 到 一 个 命 令 Unix 命令 "wc" 用于统计单词数目。要统计当前文件有多少个单词,可以这样: :write !wc 这和前面的写入命令一样,但文件名前面改为一个 "!" 用于告诉 Vim 后面是一个要被执 行的外部命令。被写入的文本将作为指定命令的标准输入。这个输出将是: 4 47 249 ~ "wc" 命令惜字如金。这表示你有 4 行,47 个单词和 249 个字符。 注意不要错写成: :write! wc 这会强制把当前文件存到当前目录的 "wc" 文件中。在这里空格的位置是非常重要的! 重 画 屏 幕 如果外部程序产生一个错误信息,屏幕显示就会乱掉。Vim 颇重效率,所以它只刷新那些 需要刷新的地方。可是它不可能知道其它程序修改了哪些地方。要强制 Vim 重画整个屏 幕: CTRL-L

下一章: |usr_11.txt| 从崩溃中恢复 版权: 参见 |manual-copyright| vim:tw=78:ts=8:ft=help:norl: