CHANGE

*change.txt*    For Vim version 6.4.  最近更新: 2006年2月


                  VIM 参考手册    by Bram Moolenaar
                                译者: Willis
                                http://vimcdoc.sf.net


本文档描述删除和修改文本的命令。在本文中,修改文本意味着用单个命令删除部分文本
并将其替换成其他文本。所有本文描述的命令都可以被撤销。其中非命令行 (Ex) 的命令
可以用 "." 命令重复。

1. 删除文本                     |deleting|
2. 删除并插入                   |delete-insert|
3. 简单修改                     |simple-change|         *changing*
4. 复杂修改                     |complex-change|
5. 复制并移动文本               |copy-move|
6. 文本排版                     |formatting|

关于插入文本部分,参阅 |insert.txt|。


1. 删除文本 *deleting* *E470*

["x]<Del>*<Del>* *x* *dl* ["x]x 删除 [count] 个光标之下和之后的字符 [到寄存器 x 里] (非 |linewise| 行动作)。和 "dl" 相同。 <Del> 键不使用 [count] 计数。相反,如果有计数,它删 除该计数的最后一位。 如果 <Del> 键的操作与你预期的不符,参见 |:fixdel|。关 于如何删除换行符 (连接行),参见 |'whichwrap'|。 {Vi 不支持 <Del>} *X* *dh* ["x]X 删除 [count] 个光标之前的字符 [到寄存器 x 里] (非 |linewise| 行动作)。和 "dh" 相同。另见 |'whichwrap'|。 *d* ["x]d{motion} 删除 {motion} 动作跨越的文本 [到寄存器 x 里]。例外见 下。 *dd* ["x]dd 删除 [count] 行 [到寄存器 x 里],|linewise| 行动作。 *D* ["x]D 删除光标所在的字符到行尾及其后的 [count]-1 行 [到寄 存器 x 里] (非 |linewise| 行动作)。和 "d$" 同义。 {Visual}["x]x 或 *v_x* *v_d* *v_<Del>* {Visual}["x]d 或 {Visual}["x]<Del> 删除高亮文本 [到寄存器 x 里] (关于 {Visual} 见 |Visual-mode|)。{Vi 无此功能} {Visual}["x]CTRL-H*v_CTRL-H* *v_<BS>* {Visual}["x]<BS> 在选择模式时,删除高亮文本 [到寄存器 x 里]。 {Visual}["x]X 或 *v_X* *v_D* *v_b_D* {Visual}["x]D 删除高亮行 [到寄存器 x 里] (关于 {Visual} 见 |Visual-mode|)。在可视列块模式里,"D" 删除高亮的文本直 到行尾。{Vi 无此功能} *:d* *:de* *:del* *:delete* :[range]d[elete] [x] 删除 [range] 范围的行 (缺省: 当前行) [到寄存器 x 里]。 :[range]d[elete] [x] {count}[range] 指定的范围开始,删除 {count} 行 (缺省: 当前 行 |cmdline-ranges|) [到寄存器 x 里]。 这些命令删除文本。你可以用 "." 命令重复它们 (除了 ":d"),也可以撤销它们。用可 视模式可以删除文本列块。关于寄存器的解释,参见 |registers|。 d{motion} 命令的一个特例: 如果动作不面向行,动作的开始和结束处不在同一行,并且 开始位置之前和结束位置之后只有空白的话,该删除会转为行动作。这意味着删除命令可 能删除你还想保留的空白行。 如果 'cpoptions' 包括 'E' 标志位,删除文本里的空区域 (例如,在首列上 "d0") 会 报错。 *J* J 连接 [count] 行,但至少包含两行。删除缩进,插入不多于 两个的空格 (见下)。 *v_J* {Visual}J 连接高亮行,但至少包含两行。删除缩进,插入不多于两个的 空格 (见下)。{Vi 无此功能}*gJ* gJ 连接 [count] 行,但至少包含两行。不插入或删除任何空 格。{Vi 无此功能}*v_gJ* {Visual}gJ 连接高亮行,但至少包含两行。不插入或删除任何空格。 {Vi 无此功能}*:j* *:join* [range]j[oin][!] 连接 [range] 范围的行。和 "J" 相同,但如有 [!] 时,连 接不插入或删除任何空格。如果 [range] 包括相同的开始和 结束行,该命令不做任何事。缺省行为是连接当前行与下一 行。{Vi: 没有 !} :[range]j[oin][!] {count} 连接 [range] 开始的 {count} 行 (缺省: 当前行 |cmdline-ranges|)。和 "J" 相同,但如有 [!] 时,连接不 插入或删除任何空格。{Vi: 没有 !} 这些命令删除行间的 <EOL>,即换行符,从而实际上使多行连接成一行。除了 ":j" 之 外,你可以重复这些命令或者撤销之。 这些命令,除了 "gJ" 以外,插入一个空格以代替 <EOL>,除非当前行的结尾已经有空白 或者下一行以 ')' 开始。这些命令,除了 "gJ" 之外,也删除下一行所有开头的空白。 如果 'joinspaces' 选项打开,这些命令在 '.'、'!' 或者 '?' 之后插入两个空格 (但 如果 'cpoptions' 包括 'j' 标志位,只有在 '.' 之后插入两个空格)。 'formatoptions' 里的 'B' 和 'M' 标志位改变在多字节字符之前或者之后插入空格的行 为 |fo-table|。

2. 删除并插入 *delete-insert* *replacing*

*R* R 进入替换模式: 每个输入的字符替代一个现有的字符,从光标 所在的位置开始。重复输入的文本 [count] - 1 次。参见 |Replace-mode| 以了解相关详情。 *gR* gR 进入虚拟替换模式: 每个输入的字符替代屏幕位置一个现有的 字符。因而,一个 <Tab> 可以一次替换若干个字符。重复输 入的文本 [count]-1 次。参见 |Virtual-Replace-mode| 以 了解相关详情。{only 仅当编译时加入 +vreplace 特性有效} *c* ["x]c{motion}{motion} 跨过的文本删除 [到寄存器 x 里] 并开始插 入。如果 'cpoptions' 包括 'E' 标志位并且没有任何文本实 际需要删除时 (例如,"cTx" 而光标刚在 'x' 之后的时候), 报错并拒绝开始插入模式 (这与 Vi 兼容)。如果 'cpoptions' 没有 'E',"c" 命令总是启动插入模式,即使没 有文本要删除也是如此。 *cc* ["x]cc 删除 [count] 行 [到寄存器 x 里] 并开始插入。 |linewise| 行动作。如果置位 'autoindent',保留首行的缩 进。 *C* ["x]C 从当前光标位置删除到行尾,再删除 [count]-1 行 [到寄存 器 x 里],并开始插入。和 c$ 等价 (非 |linewise| 行动 作)。 *s* ["x]s 删除 [count] 个字符 [到寄存器 x 里],并开始插入。(s 代 表替代 (Substitute))。和 "cl" 等价 (非 |linewise| 行动 作)。 *S* ["x]S 删除 [count] 行 [到寄存器 x 里] 并开始插入。和 "cc" 等 价 |linewise| 行动作。 {Visual}["x]c or *v_c* *v_s* {Visual}["x]s 删除高亮文本 [到寄存器 x 里],并开始插入 (关于 {Visual} 参见 |Visual-mode|)。{Vi 无此功能}*v_r* {Visual}["x]r{char} 把所有高亮的字符替换成 {char}*v_C* {Visual}["x]C 删除高亮行 [到寄存器 x 里] 并开始插入。在可视列块模式 下有所不同 |v_b_C|。{Vi 无此功能}*v_S* {Visual}["x]S 删除高亮行 [到寄存器 x 里] 并开始插入 (关于 {Visual} 参见 |Visual-mode|)。{Vi 无此功能}*v_R* {Visual}["x]R 现在和 {Visual}["x]S 相同。以后的版本可能会有所改变 {Vi 无此功能}注意: - 你可以用 <Esc> 退出插入和替换模式。 - 参见 "插入和替换模式" 一节 |mode-ins-repl| 以了解其他这些模式下的特殊字符。 - [count] 的效果只有在 Vim 退出插入或替换模式时才会体现。 - 当 'cpoptions' 选项包含 '$' 并且所做的修改在一行之内,Vim 继续显示被删除的文 本,并在最后一个被删除的字符之后加上一个 '$'。 关于寄存器的解释,参见 |registers|。 替换模式和插入模式类似,除了每输入一个字符同时删除一个字符以外。如果到达行尾, Vim 把其后的字符插入在行尾 (和插入模式相同)。在替换模式下,退格键恢复原来的文 本 (如果有的话)。(参见 "插入和替换模式" 一节 |mode-ins-repl|)。 *cw* *cW* 特殊情况: 如果光标在非空白字符上,"cw" 和 "cW" 与 "ce" 和 "cE" 相同。这是因为 Vim 把 "cw" 解释为 修改-单词,而单词并不包括其后的空白。{Vi: 在其后还有空白的 空白字符上 "cw" 只修改第一个空白;这也许是一个漏洞,因为 "dw" 删除所有空白;用 'cpoptions' 里的 'w' 标志位来设置类似于 Vi 的工作方式} 如果你希望 "cw" 包括单词之后的空格,使用如下的映射: :map cw dwi *:c* *:ch* *:change* :{range}c[hange] 用另外的文本替换若干文本行。输入只包含 "." 的行结束替 换。如果没有 {range},该命令只置换当前行。

3. 简单修改 *simple-change*

*r* r{char} 把光标下的字符换成 {char}。如果 {char}<CR> 或者 <NL>,则把该字符变成换行符。要换成一个真正的 <CR>,使 用 CTRL-V <CR>CTRL-V <NL> 则换成 <Nul>{Vi: CTRL-V <CR> 还是换成换行符。没有办法换成 <CR>}。 如果你给出 [count],Vim 替换 [count] 个字符为 [count]{char}。不过如果 {char}<CR> 或者 <NL>,Vim 只插 入一个换行符: "5r<CR>" 替换五个字符为一个换行符。 当 {char}<CR> 或者 <NL>,Vim 会自动缩进。这和先执 行删除要替换的字符在执行 "i<CR><Esc>" 类似。 {char} 可以输入二合字母 |digraph-arg|。 |:lmap| 映射会应用在 {char} 上。插入模式下的 CTRL-^ 命 令可以切换这一功能 |i_CTRL-^|。 参见 |utf-8-char-arg| 以了解在 'encoding' 为 Unicode 编码时如果使用合成用字符。 *gr* gr{char} 替换光标下的虚拟字符。替换发生在屏幕位置而不是文件位置 上。参见 |gR| 和 |Virtual-Replace-mode| 以了解相关详 情。和 |r| 一样,可以使用计数。{char} 输入的方式也相同 {only 仅当编译时加入 +vreplace 特性有效}*digraph-arg* 普通模式下的命令,像 |r| 和 |t|,需要一个单字符的参数。如果 'cpo' 不包含 'D' 标志位,该字符可以用 |digraphs| 那样的方式输入: 先键入 CTRL-K 然后输入二合字母 的两个字符 {only 仅当编译时加入 +digraphs 特性有效}*case* 下面的命令根据当前的 |locale| 改变字母的大小写。参见 |:language|。这里会用到 LC_CTYPE 的值。 *~* ~ 'notildeop' 选项: 切换光标下字符的大小写,并把光标向右 移。如果给出 [count],应用在那么多数目的字符上。 {Vi: 没有 count} ~{motion} 'tildeop' 选项: 切换 {motion} 跨越的文本的大小写。{Vi: ~ 不能用作操作符} *g~* g~{motion} 切换 {motion} 跨越的文本的大小写。{Vi 无此功能} g~g~ *g~g~* *g~~* g~~ 切换当前行的大写。{Vi 无此功能} *v_~* {Visual}~ 切换高亮文本的大小写 (关于 {Visual} 见 |Visual-mode|)。{Vi 无此功能} *v_U* {Visual}U 使高亮文本成为大写 (关于 {Visual} 见 |Visual-mode|)。 {Vi 无此功能} *gU* *uppercase* gU{motion} 使 {motion} 跨越的文本成为大写。{Vi 无此功能} 例如: :map! <C-F> <Esc>gUiw`]a 可以用在插入模式下: 按 CTRL-F 使光标之前的单词成为大 写。这使得输入大写单词很方便,只要输入小写单词再一次转 换就行了。 gUgU *gUgU* *gUU* gUU 使得当前行成为大写。{Vi 无此功能} *v_u* {Visual}u 使高亮文本成为小写 (关于 {Visual} 见 |Visual-mode|)。 {Vi 无此功能} *gu* *lowercase* gu{motion} 使 {motion} 跨越的文本成为小写。{Vi 无此功能} gugu *gugu* *guu* guu 使得当前行成为小写。{Vi 无此功能} *g?* *rot13* g?{motion} 用 Rot13 对 {motion} 跨越的文本进行编码。{Vi 无此功能} *v_g?* {Visual}g? 用 Rot13 对高亮文本进行编码 (关于 {Visual} 见 |Visual-mode|)。{Vi 无此功能} g?g? *g?g?* *g??* g?? 用 Rot13 对当前行进行编码。{Vi 无此功能} 递 增 与 递 减 *CTRL-A* CTRL-A 把当前光标之上或之后的数值或者字母加上 [count]{Vi 无此功能} *CTRL-X* CTRL-X 把当前光标之上或之后的数值或者字母减去 [count]{Vi 无此功能} CTRL-ACTRL-X 命令可用于 (带符号) 十进制数,无符号八进制和十六进制数以及字 母。这取决于 'nrformats' 选项。 - 当 'nrformats' 包括 "alpha" 时,Vim 会改变光标之上或之后的字母。这可用于构造 字母编号的列表。 - 当 'nrformats' 包括 "hex" 时,Vim 假设 '0x' 或者 '0X' 开始的数值为十六进制。 这个数值最右端的字母决定所产生十六进制数值的大小写。如果当前数值没有字母, Vim 使用上一次检测到的大小写。 - 当 'nrformats' 包括 "octal" 时,Vim 假设 '0' 开始的数值为八进制。其他的数值 为十进制,并可以在开始带一个可选的负号。 如果光标已经在数值上,命令应用于该数值;否则,应用于光标右侧的数值。 对零开头的数值 (包括八进制和十六进制的),Vim 尽可能保留相同数量的字符。CTRL-A 在 "0077" 上产生 "0100",CTRL-X 在 "0x100" 上产生 "0x0ff"。注意 如果 'nrformats' 包括 "octal",十进制不可以有开头的零,不然会和八进制数产生混淆。 CTRL-A 命令在宏命令里很有用。例如: 使用以下的步骤构造一个数字编号的列表。 1. 建立第一个列表项。确保它以数字开始。 2. qa - 用缓冲区 'a' 开始记录 3. Y - 抽出这个列表项 4. p - 把该项的一个副本放置在下一行上 5. CTRL-A - 增加计数 6. q - 停止记录 7. <count>@a - 重复抽出、放置和增加计数操作 <count> 次 将 文 本 左 移 或 右 移 *shift-left-right* *<* <{motion}{motion} 跨越的行左移 'shiftwidth' 列。 *<<* << 将 [count] 行左移 'shiftwidth' 列。 *v_<* {Visual}[count]< 将高亮行左移 [count] 个 'shiftwidth' 列 (关于 {Visual} 见 |Visual-mode|)。{Vi 无此功能} *>* >{motion}{motion} 跨越的行右移 'shiftwidth' 列。 *>>* >> 将 [count] 行右移 'shiftwidth' 列。 *v_>* {Visual}[count]> 将高亮行右移 [count] 个 'shiftwidth' 列 (关于 {Visual} 见 |Visual-mode|)。{Vi 无此功能} *:<* :[range]< 将 [range] 指定的行左移 'shiftwidth' 列。多个 '<' 左移 多个 'shiftwidth' 列。 :[range]< {count} 左移 [range] 开始的 {count} 行 'shiftwidth' 列 (缺省从 当前行 |cmdline-ranges|)。多个 '<' 左移多个 'shiftwidth' 列。 :[range]le[ft] [indent] 左对齐 [range] 指定的行。设置缩进距离为 [indent] (缺省 为 0)。{Vi 无此功能} *:>* :[range]> 将 [range] 指定的行右移 'shiftwidth' 列。多个 '>' 右移 多个 'shiftwidth' 列。 :[range]> {count} 右移 [range] 开始的 {count} 行 'shiftwidth' 列 (缺省从 当前行 |cmdline-ranges| 开始)。多个 '>' 右移多个 'shiftwidth' 列。 ">" 和 "<" 命令可以用来方便地调整程序的缩进。使用 'shiftwidth' 选项设置这些命 令增加或者减少的空白的数量。通常,'shiftwidth' 选项是 8,但你也可以设置为,比 如说,3,使得缩进更小些。如果已经没有缩进,左移命令会停止。另一方面,右移命令 则不会影响空白行。 如果 'shiftround' 选项打开,缩进距离被取整到 'shiftwidth' 的倍数。 如果 'smartindent' 选项打开,或者 'cindent' 打开并且 'cinkeys' 包含 '#',右移 不影响 '#' 开始的行 (这些应该是 C 预处理行,它们应该保持在第一列)。 如果 'expandtab' 选项关闭 (这是缺省值), Vim 尽可能使用 <Tab> 来构成缩进。你可 以用 ">><<" 来把缩进尽可能从空格替换成同样缩进距离的 <Tab> (如有需要,还有少量 的空格)。如果 'expandtab' 选项打开,Vim 只使用空格。这样你可以使用 ">><<" 把 <Tab> 替换成空格 (或者可以用 ":retab!")。 要移动一行多个 'shiftwidth' 列,使用可视模式或者 ":" 命令。例如: Vjj4> 右移三行四个缩进位 :<<< 左移当前行三个缩进位 :>> 5 右移五行两个缩进位 :5>> 右移第五行两个缩进位

4. 复杂修改 *complex-change*

*!* *filter* !{motion}{filter}{motion} 跨越的行用外部程序 {filter} 过滤。 *!!* !!{filter}[count] 行用外部程序 {filter} 过滤。 *v_!* {Visual}!{filter} 将高亮行用外部程序 {filter} 过滤。(关于 {Visual} 见 |Visual-mode|)。{Vi 无此功能} :{range}![!]{filter} [!][arg] *:range!*{range} 指定的行用外部程序 {filter} 过滤。Vim 把可 选的感叹号替换成最后一次使用的命令,并附加上可选的参数 [arg]。Vim 把过滤命令的输出保存到临时文件,并把文 件内容读到一个缓冲区里。Vim 使用 'shellredir' 选项把过 滤程序的结果重定向到临时文件。 如果 'cpoptions' 包含 'R' 标志位,过滤行里的位置标记被 删除,除非使用了 |:keepmarks| 命令。例如: :keepmarks '<,'>!sort 如果过滤后的行数变少,删去的行里的位置标记无论如何不会 保存。 *=* ={motion}{motion} 跨越的行用 'equalprg' 选项指定的外部程序过 滤。如果 'equalprg' 选项为空 (缺省),使用内部的排版机 制 |C-indenting|。但如果 'indentexpr' 非空,则使用之。 |indent-expression|. *==* == 和 ={motion} 类似,过滤 [count] 行。 *v_=* {Visual}= 和 ={motion} 类似,过滤高亮行。{Vi 无此功能} 过滤程序是一个接受文本作为标准输入,作某些修改,并把结果放到标准输出的程序。你 可以用以上的命令把若干文本发送给过滤程序。一个过滤程序的例子是 "sort",按字母 顺序给行排序;还有 "indent",排版 C 程序文件 (你需要一个能以过滤程序方式工作的 版本,并非所有的版本都可以)。'shell' 选项指定 Vim 使用的外壳程序,用以执行过滤 程序 (另见 'shelltype' 选项)。你可以用 "." 重复过滤命令。Vim 不会识别 ":!" 命 令之后的注释 (用 '"' 开始)。 *:s* *:su* *:substitute* :[range]s[ubstitute]/{pattern}/{string}/[&][c][e][g][p][r][i][I] [count][range] 指定的行把 {pattern} 的匹配替代成 {string}。 关于 {pattern},参见 |pattern|。 {string} 可以是按字面意义的,也可以包含特殊字符。 参见 |sub-replace-special|。 如果不指定 [range][count],仅在当前行进行替代。 如果指定 [count],在 [range] 最后一行开始的 [count] 行进行替代。如果不指定 [range] ,则从当前行开始。 另见 |cmdline-ranges|。 关于标志位,参见 |:s_flags|。 :[range]s[ubstitute] [c][e][g][p][r][i][I] [count] :[range]&[&][c][e][g][p][r][i][I] [count] *:&* 使用最后一次 :substitute 相同的模式和替代字符串,但不 包括相同的标志位。你可以外加别的标志位 (见 |:s_flags|)。 注意 在 ":substitute" 之后,不能使用 '&' 标志位。它被 认为是一个模式分隔符。 ":substitute" 和 'c'、'g' 和 'r' 标志位之间的空格不是 必需的,但在脚本里为了避免混淆起见,最好保留它。 :[range]~[&][c][e][g][p][r][i][I] [count] *:~* 使用最后一次 :substitute 相同的替代字符串,但使用最近 使用的搜索模式作为匹配模式。这类似于 ":&r"。 关于标志位,参见 |:s_flags|。 *&* & 等价于 ":s//~/" (重复上次的 substitute)。注意 这里不记 住标志位,所以实际工作方式可能不尽相同。你可以用 ":&&" 来保持相同的标志位。 *g&* g& 等价于 ":%s//~/&" (在所有行上重复上次的 substitute,并 使用相同的标志位)。 助记: 全局 (global) 替代 (substitute)。{Vi 无此功能} *:snomagic* *:sno* :[range]sno[magic] ... 和 ":substitute" 相同,但总使用 'nomagic'。 {Vi 无此功能} *:smagic* *:sm* :[range]sm[agic] ... 和 ":substitute" 相同,但总使用 'magic'。 {Vi 无此功能} *:s_flags* 你可以在 substitute 命令里使用以下标志位: [&] 必须是首个使用的标志位: 保留和上次 substitute 相同的标志位。例如: :&& :s/this/that/& 注意 ":s" 和 ":&" 不保留标志位。 {Vi 无此功能} [c] 确认每个替代。Vim 高亮匹配的字符串 (如果使用了 |hl-IncSearch|)。你可以 输入: *:s_c* 'y' 来替代这次匹配 'l' 来替代这次匹配并退出 (助记: "last",最后) 'n' 来跳过这次匹配 <Esc> 来退出替代过程 'a' 来替代这次和以后所有的匹配 'q' 来退出替代过程 {Vi 无此功能} CTRL-E 来上卷屏幕 {Vi 无此功能,仅当编译时加入 +insert_expand 特 性才有此功能} CTRL-Y 来下卷屏幕 {Vi 无此功能,仅当编译时加入 +insert_expand 特 性才有此功能} 如果 'edcompatible' 选项打开,Vim 记住 [c] 标志位并在每次使用它时切换 是否确认,但在给出一个新的匹配模式时复位。 {Vi 没有高亮匹配部分和除了 'y' 和 'n' 之外的选择} [e] 如果模式搜索不成功,不给出错误信息。因为没产生错误,映射的过程得以继 续。这主要用来防止在映射执行过程的无匹配 ("No match") 错误中断映射。 不过,Vim 不会抑制以下的错误信息: Regular expressions can't be delimited by letters (正规表达式 不能以字母分隔) \ should be followed by /, ? or & (\ 必须后面跟 /、? 或者 &) No previous substitute regular expression (没有上次的替代正规 表达式) Trailing characters (结尾有多余的字符) Interrupted (中断) {Vi 无此功能} [g] 对行内所有的匹配进行替代。如果没有这个参数,替代只对每行的第一个匹配进 行。如果 'edcompatible' 选项打开,Vim 记住这个标志并在你每次使用该标志 时切换,但在给出一个新的匹配模式时复位。如果 'gdefault' 选项打开,这个 标志缺省打开,而 [g] 参数关闭之。 [i] 忽略模式的大小写。不使用 'ignorecase' 和 'smartcase' 选项。 {Vi 无此功能} [I] 不忽略模式的大小写。不使用 'ignorecase' 和 'smartcase' 选项。 {Vi 无此功能} [p] 显示包含最后一次替代的行。 {Vi 无此功能} [r] 仅对于不带参数的 ":&" 和 ":s" 有用。":&r" 和 ":~" 工作的方式相同: 如果 匹配模式为空,使用上一次使用的搜索模式,而不是上一次的 substitute 或者 ":global" 所使用的模式。如果最近一次使用搜索的命令就是 substitute 或者 ":global",那就没有区别了。如果最近的命令的是 "/" 那样的搜索命令,使用 那个命令的搜索模式。 带参数的 ":s",则不论如何,总是如此: :s/blue/red/ /green :s//red/ 或 :~ 或 :&r 最后的命令把 "green" 替代成 "red"。 :s/blue/red/ /green :& 最后的命令把 "blue" 替代成 "red"。 {Vi 无此功能} 注意这里没有标志位可以改变模式的 "魔术性" (magicness)。你可以用别的命令。原因 是标志位只能在跳过模式之后才能找到,而要跳过模式,必须先知道模式的 "魔术性"。 第二十二条军规! 如果 substitute 命令所用的 {pattern} 为空,该命令使用上次的 substitute 或者 ":global" 命令用过的模式。如果有 [r] 标志位,该命令使用上次 substitute、 ":global" 或者搜索命令使用的模式。 为了和 Vi 的兼容性,有两个例外: "\/{string}/" 和 "\?{string}?" 等同于 "//{string}/r"。 "\&{string}&" 等同于 "//{string}/"。 *E146* 除了用 '/' 来包围模式和替代字符串之外,你可以使用任何其他的字符,除了字母、数 字、'\'、'"' 或 '|' 之外。这可以用于 '/' 是搜索模式或替代字符串一部分的场合。 例如: :s+/+//+ 关于模式的定义,参见 |pattern|。 *sub-replace-special* *:s\=* {string} 以 "\=" 开始时,它被作为表达式来执行,参见 |sub-replace-expression|。 否则,{string} 字符串里的字符有如下的特殊含义: magic nomagic 动作 & \& 替代为完整的匹配 *s/\&* \& & 替代为 & \0 替代为完整的匹配 *\0* *s/\0* \1 替代为匹配的第一个 () 里面的内容 *s/\1* \2 替代为匹配的第二个 () 里面的内容 *s/\2* .. .. *s/\3* \9 替代为匹配的第九个 () 里面的内容 *s/\9* ~ \~ 替代为前一个 substitute 的替代字符串 *s~* \~ ~ 替代为 ~ *s/\~* \u 下一个字符成为大写 *s/\u* \U 其后字符成为大写,直到 \E 出现 *s/\U* \l 下一个字符成为小写 *s/\l* \L 其后字符成为小写,直到 \E 出现 *s/\L* \e 结束 \u、\U、\l 和 \L (注意: 不是 <Esc>!) *s/\e* \E 结束 \u、\U、\l 和 \L *s/\E* <CR> 把该行在此位置一分为二 (<CR>CTRL-V <Enter> 方式输入) *s<CR>* \r 同上 *s/\r* \<CR> 插入一个回车 (CTRL-M) (<CR>CTRL-V <Enter> 方式输入) *s/\<CR>* \n 插入一个<NL> (文件里的 <NUL>) (此处并不是换行) *s/\n* \b 插入一个 <BS> *s/\b* \t 插入一个 <Tab> *s/\t* \\ 插入单个反斜杠 *s/\\* \x 其中 x 是上面没提到的任何一个字符: 保留作将来的扩展 示例: :s/a\|b/xxx\0xxx/g 修改 "a b" 为 "xxxaxxx xxxbxxx" :s/\([abc]\)\([efg]\)/\2\1/g 修改 "af fa bg" 为 "fa fa gb" :s/abcde/abc^Mde/ 修改 "abcde" 为 "abc"、"de" (两行) :s/$/\^M/ 修改 "abcde" 为 "abcde^M" 注意: 在以前的版本里,CTRL-V 以特殊的方式处理。因为和 Vi 不兼容,该功能已经被 去掉了,现在用反斜杠来替代。 命令 文本 结果 :s/aa/a^Ma/ aa a<line-break>a :s/aa/a\^Ma/ aa a^Ma :s/aa/a\\^Ma/ aa a\<line-break>a (你需要输入 CTRL-V <CR> 来得到这里的 ^M) "\1","\2" 等里的数字是基于模式里 "\(" 出现的顺序 (从左到右)。如果一个括号组匹 配多次,最后一次的匹配被使用在 "\1","2" 等里。例如: :s/\(\(a[a-d] \)*\)/\2/ 修改 "aa ab x" 为 "ab x" 如果括号和 '|' 组合使用,如 \([ab]\)\|\([cd]\),两者有一个会不匹配,所以 \1 或 者 \2 会为空。例如: :s/\([ab]\)\|\([cd]\)/\1x/g 修改 "a b c d" 为 "ax bx x x" 以表达式方式替代 *sub-replace-expression* 当替代字符串以 "\=" 开始时,其余部分被解释为一个表达式。该功能不能递归调用。出 现在该表达式里面的 substitute() 函数不能使用 "\=" 作为替代字符串。 除了 "<CR>"、"\<CR>" 和 "\\" 以外,|sub-replace-special| 提到的字符的特殊含义 这里不适用。这样,表达式里应出现的反斜杠须加倍出现,要插入的 <CR> 之前要加上反 斜杠,如果你想分行,则使用不带反斜杠的 <CR>。 为了方便起见,<NL> 字符也被用作换行符。在这之前加上反斜杠得到一个真正的 <NL> 字符 (在文件里成为 NUL)。 完整的匹配可以用 "submatch(0)" 得到。首个括号里的匹配可以用 "submatch(1)",余 者类似。 小心: 分隔符不能出现在表达式里!可以考虑使用 "@" 或者 ":" 那样的字符。执行结果 里出现分隔符不成问题。 例如: :s@\n@\="\r" . expand("$HOME") . "\r"@ 把换行符替代为包含 $HOME 值的一个新行。 *:pro* *:promptfind* :promptf[ind] [string] 弹出搜索对话框。如果给出 [string],它被用作初始的搜索 字符串。 {only 仅适用于 Win32、Motif 和 GTK GUI 环境} *:promptr* *:promptrepl* :promptr[epl] [string] 弹出搜索/替代对话框。如果给出 [string],它被用作初始的 搜索字符串。 {only 仅适用于 Win32、Motif 和 GTK GUI 环境} *:ret* *:retab* :[range]ret[ab][!] [new_tabstop] 把所有包含 <Tab> 的空白序列替代成由新的制表位 [new_tabstop] 确定的空白序列。如果你不指定新的制表位, 或者它为 0,Vim 使用原来的制表位 'tabstop'。 已有的 Tab 的宽度总是用 'tabstop' 的当前值来计算。 如果有 !,Vim 也在合适的时候,把只包含正常空格的字符串 换成 Tab。 如果置位了 'expandtab',Vim 把所有的 Tab 换成相当的空 格。 该命令把 'tabstop' 设为新值。如果按照缺省的情况,在全 文件上进行处理,视觉上应该不会有任何改变。 小心: 该命令修改 C 程序中的字符串里的任何 <Tab> 字符。 要避免这一点,用 "\t" (无论如何,应该养成这个好的习 惯)。 ":retab!" 也把空格序列换成 <Tab>,这可能会使 printf() 引起混淆。 {Vi 无此功能,仅在编译时加入|+ex_extra| 特性才有效} *retab-example* 下面的例子使用自动命令和 ":retab" 来编辑使用制表位为 8 的文件,但在编辑时制表 位设置为 4。警告: 字符串里的空格会被改变。另见 'softtabstop' 选项。 :auto BufReadPost *.xx retab! 4 :auto BufWritePre *.xx retab! 8 :auto BufWritePost *.xx retab! 4 :auto BufNewFile *.xx set ts=4

5. 复制并移动文本 *copy-move*

*quote* "{a-zA-Z0-9.%#:-"} 指定下次的删除、抽出和放置命令使用的寄存器 {a-zA-Z0-9.%#:-"} (大写字符使得删除和抽出命令附加到该 寄存器) ({.%#:} 只能用于放置命令)。 *:reg* *:registers* :reg[isters] 显示所有编号和命名寄存器的内容。{Vi 无此功能} :reg[isters] {arg} 显示 {arg} 里提到的编号和命名寄存器的内容。例如: :dis 1a 显示寄存器 '1' 和 'a'。{arg} 里可以用空格。 {Vi 无此功能} *:di* *:display* :di[splay] [arg] 和 :registers 相同。{Vi 无此功能} *y* *yank* ["x]y{motion} 抽出 {motion} 跨越的文本 [到寄存器 x]。如果没有字符被 抽出 (例如,在第一列执行 "y0") 并且 'cpoptions' 里包括 'E' 标志位,这是一个错误。 *yy* ["x]yy 抽出 [count] 行 [到寄存器 x] |linewise| 行动作。 *Y* ["x]Y 抽出 [count] 行 [到寄存器 x] (等同于 yy,|linewise| 行 动作)。如果你想要 "Y" 执行从光标到行尾的操作 (更合乎逻 辑,但是与 Vi 不兼容),用 ":map Y y$"。 *v_y* {Visual}["x]y 抽出高亮文本 [到寄存器 x] (关于 {Visual} 见 |Visual-mode|)。{Vi 无此功能} *v_Y* {Visual}["x]Y 抽出高亮行 [到寄存器 x] (关于 {Visual} 见 |Visual-mode|)。{Vi 无此功能} *:y* *:yank* :[range]y[ank] [x] 抽出 [range] 所指定的行 [到寄存器 x]。 :[range]y[ank] [x] {count}[range] 的最后一行开始 (缺省: 当前行 |cmdline-ranges|) 抽出 {count} 行 [到寄存器 x]。 *p* *put* *E353* ["x]p 放置文本 [从寄存器 x] 在光标之后 [count] 次。{Vi: 没有 计数} *P* ["x]P 放置文本 [从寄存器 x] 在光标之前 [count] 次。{Vi: 没有 计数} *<MiddleMouse>* ["x]<MiddleMouse> 从一个寄存器放置文本在光标之前 [count] 次。除非另外指 定,否则用 "* 寄存器。只有在 'mouse' 包含 'n' 或者 'a' 时鼠标才会工作。{Vi 无此功能} 如果你有滚轮鼠标而且经常不小心粘贴了文本,你可以使用以 下映射来关闭鼠标中键粘贴的功能: :map <MiddleMouse> <Nop> :imap <MiddleMouse> <Nop> 你也许还想要关闭多键击的功能。参见 |double-click|。 *gp* ["x]gp 如同 "p",但光标停留在新文本之后。{Vi 无此功能} *gP* ["x]gP 如同 "P",但光标停留在新文本之后。{Vi 无此功能} *:pu* *:put* :[line]pu[t] [x] 放置文本 [从寄存器 x] 在行号 [line] (缺省为当前行) 之 后。它总是 |linewise| 行动作,因而这个命令可以用来把抽 出的块放置在新行上。 寄存器也可以是 '=',跟随一个可选的表达式。表达式继续到 该命令结束为止。你需要在 '|' 和 '"' 字符前加上反斜杠不 让它们终止你的命令行。例如: :put ='path' . \",/test\" 如果 '=' 之后没有表达式,Vim 使用前一个表达式。用 ":dis =" 你可以看到它。 :[line]pu[t]! [x] 放置文本 [从寄存器 x] 在行号 [line] (缺省为当前行) 之 前。 ["x]]p 或 *]p* *]<MiddleMouse>* ["x]]<MiddleMouse> 类似 "p",但调整当前行的缩进。只有在 'mouse' 包含 'n' 或者 'a' 时鼠标才会工作。{Vi 无此功能} ["x][P 或 *[P* ["x]]P 或 *]P* ["x][p 或 *[p* *[<MiddleMouse>* ["x][<MiddleMouse> 类似 "P",但调整当前行的缩进。只有在 'mouse' 包含 'n' 或者 'a' 时鼠标才会工作。{Vi 无此功能} 你可以用这些命令把文本从一个地方复制到另一个地方。首先,把文本用抽出、删除或者 修改命令取到一个寄存器里,然后用放置命令把寄存器的内容插入。你可以用这些命令把 文本从一个文件移动到另一个文件,因为 Vim 在切换缓冲区时保留所有的寄存器 (CTRL-^ 命令可用来快捷地切换文件)。 *linewise-register* *characterwise-register* 除了 :put 以外,你可以用 "." 重复放置命令,你也可以撤销它们。如果保存到寄存器 文本的命令是 |linewise| 行动作,Vim 把文本插入在光标所在的行之下 ("p") 或之上 ("P")。不然,Vim 把文本插入在光标的之后 ("p") 或之前 ("P")。":put" 命令使得 Vim 总是把文本放在下一行。你可以用命令序列 "xp" 来交换两个字母。你可以用 "ddp" 命令序列来交换两行。你还可以用 "deep" 命令交换两个单词 (光标在第一个单词之前的 空白上)。你更可以在放置命令之后用 "']" 或者 "`]" 命令把光标移动到插入文本之 后,或者用 "'[" 或 "`[" 把光标移动到文本的开始处。 *put-Visual-mode* *v_p* *v_P* 在可视模式下使用如 |p| 或者 |P| 之类的放置命令时,Vim 试图把选择的文本替换成寄 存器的内容。是否工作如你所愿决定于选择的类型和寄存器里文本的类型。对于列块选择 而言,它也决定于列块的大小,和头尾是否包含存在的字符 (实现细节: 实际上,它先把 寄存器的内容放到选择区之后,再删除选择区)。 *blockwise-register* 如果你使用面向列块的可视模式命令把文本存到寄存器里,文本列块会被插入在当前和其 后的行的当前列之前 ("P") 或之后 ("p")。Vim 使得整个文本列块从同一列开始。这样, 插入的文本看上去和抽出或删除时看起来一样。为了使之可能,Vim 可能需要把一些 <Tab> 字符替换成空格。不过,如果列块的宽度不是 <Tab> 宽度的整数倍并且插入列块 之后文本里包含 <Tab> 的时候,那些文本可能就不会那么整齐。 注意 在一个面向字符的抽出命令之后,Vim 把光标停留在最接近缓冲区开头的第一个被 抽出的字符之上。这意味着 "yl" 不会移动光标,但是 "yh" 把光标向左移一格。 逻辑: 在 Vi 里 "y" 命令跟一个反向的动作有时不会把光标移动到第一个被 抽出的字符之上,因为屏幕没有刷新。Vim 符合 Posix 的规范,总是 把光标移动到第一个字符之上。 在一个面向行的抽出命令之后,光标放在第一行上,但是列保持不变,所以不必然在第一 个抽出的字符上。 共有九种类型的寄存器: *registers* *E354* 1. 无名寄存器 "" 2. 10 个编号寄存器 "0 到 "9 3. 行内删除寄存器 "- 4. 26 个命名的寄存器 "a 到 "z 或者 "A 到 "Z 5. 四个只读寄存器 ":、".、"% 和 "# 6. 表达式寄存器 "= 7. 选择和拖放寄存器 "*、"+ 和 " 8. 黑洞寄存器寄存器 "_ 9. 最近搜索模式寄存器 "/ 1. 无名寄存器 "" *quote_quote* *quotequote* 用 "d"、"c"、"s"、"x" 等命令删除或者用 "y" 等抽出命令复制的文本都被 Vim 用来填 充该寄存器,不管是否用到别的专门寄存器 (例如 "xdd)。这就好像无名寄存器是指向最 近使用的那个寄存器的指针一样。'_' 寄存器是一个特例。"_dd 不把删除的文本存在任 何寄存器里。不指定寄存器的放置命令 (p 或 P) 使用无名寄存器的内容。你也可以用 '"' 作为名字来访问该寄存器。这意味着要输入两个连续的双引号。写入 "" 寄存器将实 际写到寄存器 "0 上。{Vi: 寄存器内容在更换文件时丢失,没有 '"'} 2. 编号寄存器 "0 到 "9 *quote_number* *quote0* *quote1* *quote2* *quote3* *quote4* *quote9* Vim 把抽出和删除命令的文本保存在这些寄存器里。 编号寄存器 0 包含最近抽出的文本,除非该命令用 ["x] 指定了别的寄存器。 编号寄存器 1 包含了最近删除或者修改的文本,除非该命令用 ["x] 指定了别的寄存 器或者该文本小于一行 (该情况下使用行内删除寄存器)。以下命令是例外: |%|、|(|、 |)|、|`|、|/|、|?|、|n|、|N|、|{| 和 |}|。这时,总是使用寄存器 "1 (为了和 Vi 兼容)。如果文本小于一行,同时使用 "- 寄存器。 每来一次新的删除和修改,Vim 把前一次的寄存器 1 的内容复制到寄存器 2,2 到 3,依此类推。而寄存器 9 的内容就丢失了。 {Vi: 编号寄存器的内容在更换文件时丢失;寄存器 0 不存在} 3. 行内删除寄存器 "- *quote_-* *quote-* 该寄存器保存删除不到一行内容的命令的文本,除非该命令用 ["x] 指定了寄存器。 {Vi 无此功能} 4. 命令寄存器 "a 到 "z 或者 "A 到 "Z *quote_alpha* *quotea* Vim 只有在你指定的时候才使用这些寄存器。指定为小写字母时替换原来的内容,指定为 大写字母时附加到原来的内容。 5. 只读寄存器 ":、".、"% 和 "# 它们是 '%'、'#'、':' 和 '.'。你只能在 "p"、"P"、":put" 命令和 CTRL-R 的时候使 用它们。{Vi 无此功能} *quote_.* *quote.* *E29* ". 包含最近插入的文本 (和插入模式命令 CTRL-ACTRL-@ 插入的一 样)。注意: 它不适用于 CTRL-R 在命令行上的操作。它的工作方式稍 有不同,例如,文本是被插入而不是放置的 ('textwidth' 和其它选项 影响插入的内容)。 *quote_%* *quote%* "% 包含当前文件名。 *quote_#* *quote#* "# 包含轮换文件名。 *quote_:* *quote:* *E30* ": 包含最近执行过的命令行。例如: 用 "@:" 重复上次执行过的命令行命 令。只有当一个命令行中至少一个字符是键入的,该寄存器才会保存命 令行的内容。所以,如果命令行完全来自映射,该寄存器保持不变。 {only 仅当编译时加入 |+cmdline_hist| 特性才有效} 6. 表达式寄存器 "= *quote_=* *quote=* 其实并没有这么一个寄存器可以储存文本,但是这是用来在使用寄存器的命令中使用表达 式的一个方式。表达式寄存器是只读的,你不能把文本放置其中。在 '=' 之后,光标移 到命令行上,这时你可以输入任何的表达式 (见 |expression|)。所有普通的命令行编辑 命令都可以使用,还有一个表达式专门的历史表。当你按回车结束命令行时,Vim 计算表 达式的结果。如果你用 <Esc> 结束,Vim 终止表达式。如果你不输入表达式,Vim 使用 最近的表达式 (和 "/" 命令的处理相似)。如果 "= 寄存器被 "p" 命令使用,该字符串 会在 <NL> 字符处断开。如果该字符串以 <NL> 结尾,则它被视为一个面向行的寄存器。 {Vi 无此功能} 7. 选择和拖放寄存器 "*、"+ 和 " 用这些寄存器来保存和取得 GUI 界面选择的文本。参见 |quotestar| 和 |quoteplus|。 如果剪贴板不存在 (X11 需要 |+xterm_clipboard| 特性) 或者不工作,则使用无名寄存 器。{Vi 无此功能} 注意 "* 和 "+ 在 X11 系统上有分别。关于该差别的解释,参见 |x11-selection|。在 MS-Windows 上,"* 和 "+ 的使用实际上是等价的,可见 |gui-clipboard|。 *quote_~* *quote~* *<Drop>* 只读的 "~ 寄存器保存最近一次拖放操作放下的文本。如果有什么东西被放到 Vim 上, "~ 寄存器被填充,<Drop> 虚拟键被激活。如果你需要,你可以重定义该键的映射;缺省 的动作 (适用于所有模式) 是把 "~ 寄存器的内容插入到当前光标位置。{Vi 无此功能} {only 仅当编译时加入 |+dnd| 特性才有效,当前只适用于 GTK GUI 版本} 注意: "~ 寄存器仅用于在 Vim 上拖放普通文本。拖放 URI 列表在内部处理。 8. 黑洞寄存器 "_ *quote_* 当写到这个寄存器时,什么都不会发生。这可以用来删除文本,而不影响任何正常的寄存 器。从该寄存器读时,什么都不会返回。{Vi 无此功能} 9. 最近搜索模式寄存器 "/ *quote_/* *quote/* 含有最近搜索的模式。它被 "n" 和 'hlsearch' 使用。可以用 ":let" 来修改。你可以 改变它使得 'hlsearch' 不经过实际的搜索直接高亮某些匹配。你不能把抽出或者删除命 令的内容放到该寄存器上。{Vi 无此功能} *@/* 你可以用 ":let" 命令写到一个寄存器 |:let-@|。例如: :let @/ = "the" 如果你用放置命令而不指定寄存器,Vim 使用上次填充的寄存器 (这也是无名寄存器的内 容)。如果你弄糊涂了,用 ":dis" 命令看看 Vim 会放置什么内容 (该命令显示所有的有 名和无名的寄存器;无名寄存器被标为 '"')。 下面三个命令总是针对整行工作。 :[range]co[py] {address} *:co* *:copy*[range] 指定的行复制到 {address} 给出的行之下。 *:t* :t 和 :copy 等价。 :[range]m[ove] {address} *:m* *:mo* *:move* *E134*[range] 指定的行移动到 {address} 给出的行之下。

6. 文本排版 *formatting*

:[range]ce[nter] [width] *:ce* *:center*[range] 指定范围的行和 [width] 限定的列 (缺省为 'textwidth',如其为 0,则取 80) 范围内的文本居中对齐。 {Vi 无此功能} 只有在编译时加入 |+ex_extra| 特性时才有此功能。 :[range]ri[ght] [width] *:ri* *:right*[range] 指定范围的行和 [width] 限定的列 (缺省为 'textwidth',如其为 0,则取 80) 范围内的文本靠右对齐。 {Vi 无此功能} 只有在编译时加入 |+ex_extra| 特性时才有此功能。 *:le* *:left* :[range]le[ft] [indent] 在 [range] 指定范围的行的文本靠左对齐。其缩进的距离可 由 [indent] 设置 (缺省为 0)。 {Vi 无此功能} *gq* gq{motion}{motion} 动作跨越的行进行排版。'textwidth' 选项控制 所有待排版行的行宽 (见下)。如果 'textwidth' 选项为 0, 则排版行宽设为屏幕的宽度 (但最大宽度不超过 79)。 {Vi 无此功能} 'formatoptions' 选项控制排版的方式 |fo-table|。 注意: "Q" 命令以前执行此项功能。如果你还想继续用 "Q" 来排版,执行如下映射命令: :nnoremap Q gq gqgq *gqgq* *gqq* gqq 排版当前行。{Vi 无此功能} *v_gq* {Visual}gq 排版高亮文本 ({Visual} 的部分参见 |Visual-mode|)。 {Vi 无此功能} *gw* gw{motion}{motion} 动作跨越的行进行排版。和 |gq| 类似,但排版 后光标恢复原位,而且不使用 'formatprg' 选项。 {Vi 无此功能} gwgw *gwgw* *gww* gww 对当前行排版,其它和 "gw" 类同。{Vi 无此功能} *v_gw* {Visual}gw 排版高亮文本,其它和 "gw" 类同。({Visual} 可见 |Visual-mode|)。{Vi 无此功能} 例如: 要排版当前段落,可用: *gqap* gqap "gq" 命令后,光标随着指定的移动命令移动。这使得用 "." 进行连续排版成为可能。例 如,"gqj" (对当前行和下一行排版) 和 "gq}" (排版到段落尾) 便可如此。注意: 如果 设置了 'formatprg',"gq" 把光标留在排版后的首行 (如同过滤命令那般)。 如果你想对当前段落排版后留在原来的位置,可用: gwap 如果你想使段落自动排版,可以在 'formatoptions' 里加入 'a' 标志位。参见 |auto-format|。 如果 'autoindent' 选项打开,Vim 用首行的缩进距离排版其后的所有行。 排版不会改变空行 (但会改变只有空白字符的行!)。 如果有连接行的操作,应用 'joinspaces' 选项。 你可以设置 'formatprg' 选项来指定外部程序的名字。Vim 会使用该程序进行文本排 版。'textwidth' 等选项对外部程序的排版不起作用。 *right-justify* Vim 没有靠右控制对齐 (right justify) 文本的命令。你可以用 "par" 这样的外部命令 来实现 (例如, "!}par" 对到段落尾的文本排版),或者设置 'formatprg' 为 "par"。 *format-comments* Vim 可以对注释的排版进行特殊处理。Vim 把以特定字符串开头 (忽略空白) 的行识别 为注释。以下是三种不同类型的注释: - 在每行的开头都出现的注释字符串。例如,外壳脚本使用的注释行都以 "#" 开头。 - 只在首行出现的注释字符串。使用连字符 "-" 的本列表就是这样的一个例子, - 由三部分组成的注释,包括起始字符串,结尾字符串,和两者之间可选的行的起始字符 串。三种字符串可分别指定。如下 C-风格的注释就是如此: /* * this is a C comment */ 'comments' 选项是一个由逗号分隔的列表。每个部分定义一种类型的注释字符串。每个 部分的组成方式是: {flags}:{string} {string} 是必须出现的字符串 (不作转义)。 {flags}: n 可嵌套的注释: 允许多个部分间的嵌套。例如,'comments' 为 "n:),n:>"。则 以 "> ) >" 开始的行视为注释。 b 在 {string} 之后必须有空白字符 (<Space><Tab><EOL>)。 f 该注释字符串只在首行出现。下一行不重复注释,但保留相同的缩进 (例如,带 符号的列表 (bullet-list))。 s 三段式注释的起始字符串 m 三段式注释的中间字符串 e 三段式注释的结尾字符串 l 使中间字符串和起始或结尾字符串左对齐 (缺省)。只有在和 's' 或 'e' 一起 使用时方有效。 r 使中间字符串和起始或结尾字符串右对齐。只有在和 's' 或 'e' 一起使用时方 有效。 O 不适用于 "O" 命令。 x 允许三段式注释用以下方式结束: 在中间字符串自动提供的情况下,在新行第一 个字符输入结尾字符串的最后一个字符。详情见下。 {digits} 在和 's' 或 'e' 一起使用时: 对中间部分增加额外的缩进。这可以用来使中间 部分和开始或结尾部分左对齐,并在此基础上增加一定的偏移。 -{digits}{digits} 类似,但减少缩进。这只对开始或结尾部分至少有相当数量的缩进 时才有效。 如果一个字符串没有 'f'、's'、'm' 或 'e' 任何一个标志位,Vim 假设注释字符串在每 行都重复出现。标志位部分可以为空。 在 {string} 之前或之后的任何空白都是 {string} 的一部分,所以不要随便留出开头或 结尾的空白,除非空白的确是注释字符串的一部分。 如果某个注释字符串是另一个字符串的一部分,先指定完整的,再指定部分的。例如,要 包含 "-" 和 "->",用 :set comments=f:->,f:- 三段式注释必须以开始、中间和结尾三部分给出,而且不能间杂其它的部分。一个三段式 C 注释的例子是 sr:/*,mb:*,ex:*/ 为了避免形如 "*ptr" 的内容被识别为注释,这里的中间字符串包含了 'b' 标志位。对 三段式注释而言,Vim 从开始和中间字符串之后查找结尾字符串。如果找到,注释就不会 再从下一行继续。三段式注释必须要有一个中间字符串,不然 Vim 无法识别中间的那些 行。 注意 上述三段式注释定义里的 "x" 标志位。当你在一个 C-注释里按回车时,Vim 会自 动在新行后插入中间字符串,例如 " * "。要结束注释,你只需要在新行里首先键入 "/"。这样就把中间字符串替换成结尾字符串,成为了 " */"。从而省却了先按退格键的 麻烦。 示例: "b:*" 包含 "*" 开头的行,但 "*" 后面不是空白的除外。这样避免指针取值 操作 "*str" 被识别为注释。 "n:>" 包含形如 ">"、">>"、">>>" 等开头的行。 "fb:-" 包含 "- " 开头的列表,可用来自动排版。 该选项的缺省值是 "b:#"。这意味着 "#include" 开头的行不会被认为是注释,但 "# define" 是。这是个不得不然的妥协。 除了右对齐以外,人们经常使用带一定空白的左对齐方式。例如,Javadoc 注释可用以下 方式表示 (如果用 ":set" 命令设置,在空格前加入反斜杠): s1:/*,mb:*,ex:*/ 注意 开始字符串包含位移,所以中间部分会先和开始部分对齐,再偏移一个字符。这使 得开始和中间部分可以对齐如下: /** * comment */ {only 只有在编译时加入 |+comments| 特性才有效} *fo-table* 你可以使用 'formatoptions' 选项来控制 Vim 如何对文本进行排版。'formatoptions' 是一个字符串,它可以包含下列字符。缺省设置是 "tcq"。为了提高可读性,你可以用逗 号分隔选项字符。 字符 在 'formatoptions' 里代表的含义 t 使用 'textwidth' 自动回绕文本 (对注释不适用) c 使用 'textwidth' 自动回绕注释,自动插入当前注释前导符。 r 在插入模式按回车时,自动插入当前注释前导符。 o 在普通模式按 'o' 或者 'O' 时,自动插入当前注释前导符。 q 允许 "gq" 排版时排版注释。 注意 排版不会影响空行或者只有注释前导符的行。这样的行开启一个新段落, 注释前导符的改变也是如此。 w 拖尾的空格指示下一行继续同一个段落。而以非空白字符结束的行结束一个段 落。 a 自动排版段落。每当文本被插入或者删除时,段落都会自动进行排版。参见 |auto-format|。 如果 'c' 标志位存在,该设置只对识别的注释有效。 n 在对文本排版时,识别编号的列表。出现在数字之后的文本缩进距离被应用到后 面的行。数字之后可以有可选的 '.'、':'、')'、']' 或者 '}'。 注意 'autoindent' 也必须置位。不要和 "2" 一起使用,效果不好。 示例: 1. 第一项 回绕文字 2. 第二项 2 在对文本排版时,将段落第二行而非第一行的缩进距离应用到其后的行上。这适 用于第一行有特殊缩进需要的段落。注意 'autoindent' 也必须置位。 示例: first line of a paragraph second line of the same paragraph third line. v Vi-兼容的插入模式自动回绕: 只有在当前输入命令键入的空白上才会分行。 (注意: 这并不能 100% Vi 兼容。Vi 在这方面有些 "意想不到的特性",换而言 之,漏洞。它使用屏幕列而非实际的列。) b 和 'v' 类似,但只有在键入空白时还没抵达或者刚到回绕边界的时候才会自动 回绕。如果一行在开始插入之前已经超过 'textwidth' 指定的长度,或者在到 达 'textwidth' 之时没有输入过空白,Vim 不会自动回绕。 l 插入模式不分行: 当一行已经超过 'textwidth' 时,插入命令不会自动排版。 m 可以在任何值高于 255 的多字节字符上分行。这对亚洲文本尤其有用,因为每 个字符都是单独的单位。 M 在连接行时,不要在多字节字符之前或之后插入空格。优先于 'B' 标志位。 B 在连接行时,不要在两个多字节字符之间插入空格。有 'M' 标志位时无效。 1 不要在单字母单词后分行。如有可能,在它之前分行。 't' 和 'c' 不同组合方式决定 Vim 何时进行自动回绕: 值 行为 "" 没有自动排版 (你可以用 "gq" 进行手工排版) "t" 自动排版文本,不包括注释 "c" 自动排版注释,不包括文本 (对 C 程序适用) "tc" 自动排版文本和注释 注意 如果 'textwidth' 为 0,Vim 不会做任何排版 (但是会根据 'comments' 选项自动 插入注释前导符)。 注意 如果 'paste' 打开,Vim 也不会做任何排版。 注意 即使 Vim 不做自动回绕,仍然可以把 'textwidth' 设为非零。'textwidth' 对 "gq" 的排版依然有用。 如果 'comments' 选项包含 "/*"、"*" 和/或 "*/",Vim 有一套处理这些注释更加聪明 的内嵌方法。在 "/*" 或 "*/" 之前或之后开始一个新行 (在 'formatoptions' 里有 'r' 或者 'o' 的情况下),会自动给出正确的开始部分。排版或者自动回绕也会有相同的 处理。在以 "/*" 或者 "*" 开始并包含 "*/" 的行之后开启新行,就不会插入注释前导 符,而且新行的缩进由注释起始行决定。 例如: /* * 你的任何注释。 */ 该行的缩进和以上注释的起始行相同。 上述这些应该已经十分够用了,尤其在与新的 :autocmd 命令协同使用时,可以为不同文 件类型提供不同的设置。 一些例子: 适用于 C 代码 (只对注释排版): :set fo=croq 适用于邮件/新闻 (排版所有文本,"o" 命令不开始注释): :set fo=tcrq 自动排版 *auto-format* 如果 'formatoptions' 里包含 'a' 标志位,在插入或者删除文本时会自动进行排版。这 对编辑文本段落很好用。以下对如何使用这一功能提供一些提示: - 你需要正确定义何谓段落。最简单的方式是以空行分隔的为段落。如果没有分隔的空 行,考虑用 'w' 标志位并在段落中除了最后一行以外,每行结尾加上一个空格。 - 你可以根据文件类型 |filetype|, 或者用 |modeline| 指定特定文件的方式,设置不 同的 'formatoptions'。 - 将 'formatoptions' 设为 "aw2tq" 使得文本以如下方式缩进: bla bla foobar bla bla foobar bla foobar bla bla bla foobar bla bla foobar bla bla foobar - 如果只想自动排版注释,加上 'c' 标志位。可用于源代码。 还有一些警告: - 如果段落没有正确分隔,任何改变都会使得所有相连的文本自动排版。考虑 :set fo-=a - 如果用 'w' 标志位 (行尾的空格意味着段落的继续) 并且用 |dd| 删除了段落的末 行,这段落自动和下一个段落合并为一个段落。 - 改变的文本被保存以备可能的撤销之用。排版也是改变的一种。所以每次排版都会为撤 销保存文本。这会有相当的内存开销。 - 排版一个很长的段落和/或复杂的缩进也许会相当慢。 vim:tw=78:ts=8:ft=help:norl:

Generated by vim2html on 2006年 07月 02日 星期日 22:43:25 UTC