*change.txt*    For Vim version 7.3.  最近更新: 2010年8月


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


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

1. 删除文本			|deleting|
2. 删除并插入			|delete-insert|
3. 简单修改			|simple-change|		*changing*
4. 复杂修改			|complex-change|
   4.1 过滤命令			   |filter|
   4.2 替代			   |:substitute|
   4.3 搜索与替代		   |search-replace|
   4.4 调整制表			   |change-tabs|
5. 复制并移动文本		|copy-move|
6. 文本排版			|formatting|
7. 文本排序			|sorting|

关于插入文本部分，参阅 |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$" 同义。
			如果 'cpoptions' 里有 '#' 标志位，忽略计数。

{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][!] [flags]
			连接 [range] 范围的行。和 "J" 相同，但如有 [!] 时，连
			接不插入或删除任何空格。如果 [range] 包括相同的开始和
			结束行，该命令不做任何事。缺省行为是连接当前行与下一
			行。{Vi: 没有 !}
			[flags] 部分可参见 |ex-flags|。

:[range]j[oin][!] {count} [flags]
			连接 [range] 开始的 {count} 行 (缺省: 当前行
			|cmdline-ranges|)。和 "J" 相同，但如有 [!] 时，连接不
			插入或删除任何空格。{Vi: 没有 !}
			[flags] 部分可参见 |ex-flags|。

这些命令删除行间的 <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| 以
			了解相关详情。{仅当编译时加入 |+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" 不包含单词后的空白而只修改到词尾。
这是因为 Vim 把 "cw" 解释为 修改-单词，而单词并不包括其后的空白。{Vi: 在其后还
有空白的空白字符上 "cw" 只修改第一个空白；这也许是一个漏洞，因为 "dw" 删除所有
空白；用 'cpoptions' 里的 'w' 标志位来设置类似于 Vi 的工作方式}

如果你希望 "cw" 包括单词之后的空格，使用如下的映射: >
	:map cw dwi
或者，用 "caw" (见 |aw|)。

							*:c* *:ch* *:change*
:{range}c[hange][!]	用另外的文本替换若干文本行。输入只包含 "." 的行结束替
			换。如果没有 {range}，该命令只置换当前行。
			加上 [!] 后，在本命令的执行期间切换 'autoindent'。

==============================================================================
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} 输入的方式也相同
			{仅当编译时加入 |+vreplace| 特性有效}。

						*digraph-arg*
普通模式下的命令，像 |r| 和 |t|，需要一个单字符的参数。如果 'cpo' 不包含 'D'
标志位，该字符可以用 |digraphs| 那样的方式输入: 先键入 CTRL-K 然后输入二合字母
的两个字符 {仅当编译时加入 |+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 无此功能}

要以标题大写 (title cap) 方式改写一行，亦即使每个单词的首字母大写: >
	:s/\v<(.)(\w*)/\u\1\L\2/g


递 增 与 递 减 ~
							*CTRL-A*
CTRL-A			把当前光标之上或之后的数值或者字母加上 [count]。
			{Vi 无此功能}

							*CTRL-X*
CTRL-X			把当前光标之上或之后的数值或者字母减去 [count]。
			{Vi 无此功能}

CTRL-A 和 CTRL-X 命令可用于 (带符号) 十进制数，无符号八进制和十六进制数以及字
母。这取决于 'nrformats' 选项。
- 当 'nrformats' 包括 "octal" 时，Vim 假设 '0' 开始的数值为八进制，除非该数值
  里包含 '8' 或 '9'。其他的数值为十进制，并可以在开始带一个可选的负号。
  如果光标已经在数值上，命令应用于该数值；否则，应用于光标右侧的数值。
- 当 'nrformats' 包括 "alpha" 时，Vim 会改变光标之上或之后的字母。这可用于构造
  字母编号的列表。
- 当 'nrformats' 包括 "hex" 时，Vim 假设 '0x' 或者 '0X' 开始的数值为十六进制。
  这个数值最右端的字母决定所产生十六进制数值的大小写。如果当前数值没有字母，
  Vim 使用上一次检测到的大小写。

对零开头的数值 (包括八进制和十六进制的)，Vim 尽可能保留相同数量的字符。CTRL-A
在 "0077" 上产生 "0100"，CTRL-X 在 "0x100" 上产生 "0x0ff"。
有一个例外: 在发现某数值以零开始但不是八进制 (包含 '8' 或 '9')，而 'noformats'
却包含 "octal" 的时候，引导的零会被删除，以免结果被误认为八进制。

注意 如果 '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]> [flags]	将 [range] 指定的行右移 'shiftwidth' 列。多个 '>' 右移
			多个 'shiftwidth' 列。
			[flags] 部分可参见 |ex-flags|。

:[range]> {count} [flags]
			右移 [range] 开始的 {count} 行 'shiftwidth' 列 (缺省从
			当前行 |cmdline-ranges| 开始)。多个 '>' 右移多个
			'shiftwidth' 列。
			[flags] 部分可参见 |ex-flags|。

">" 和 "<" 命令可以用来方便地调整程序的缩进。使用 '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*

4.1 过滤命令						*filter*

过滤程序是一个接受文本作为标准输入，作某些修改，并把结果放到标准输出的程序。你
可以用下面的命令把若干文本发送给过滤程序，然后用过滤的输出结果替换。一个过滤程
序的例子是 "sort"，按字母顺序给行排序；还有 "indent"，排版 C 程序文件 (你需要
一个能以过滤程序方式工作的版本，并非所有的版本都可以)。'shell' 选项指定 Vim 使
用的外壳程序，用以执行过滤程序 (另见 'shelltype' 选项)。你可以用 "." 重复过滤
命令。Vim 不会识别 ":!" 命令之后的注释 (用 '"' 开始)。

							*!*
!{motion}{filter}	将 {motion} 跨越的行用外部程序 {filter} 过滤。

							*!!*
!!{filter}		将 [count] 行用外部程序 {filter} 过滤。

							*v_!*
{Visual}!{filter}	将高亮行用外部程序 {filter} 过滤。(关于 {Visual}
			见 |Visual-mode|)。{Vi 无此功能}

:{range}![!]{filter} [!][arg]				*:range!*
			将 {range} 指定的行用外部程序 {filter} 过滤。Vim 把可
			选的感叹号替换成最后一次使用的命令，并附加上可选的参数
			[arg]。Vim 把过滤命令的输出保存到临时文件，并把文
			件内容读到一个缓冲区里 |tempfile|。Vim 使用
			'shellredir' 选项把过滤程序的结果重定向到临时文件。
			不过，如果关闭了 'shelltemp' 选项且可以的话，使用管道
			机制 (Unix 上)。
			如果 'cpoptions' 包含 'R' 标志位，过滤行里的位置标记被
			删除，除非使用了 |:keepmarks| 命令。例如: >
				:keepmarks '<,'>!sort
<			如果过滤后的行数变少，删去的行里的位置标记无论如何不会
			保存。

							*=*
={motion}		把 {motion} 跨越的行用 'equalprg' 选项指定的外部程序过
			滤。如果 'equalprg' 选项为空 (缺省)，使用内部的排版机
			制 |C-indenting|。但如果 'indentexpr' 非空，则使用之。
			|indent-expression|。如果 Vim 编译时不包含内部排版机
			制，作为最后的手段，使用外部的 "indent" 程序。

							*==*
==			和 ={motion} 类似，过滤 [count] 行。

							*v_=*
{Visual}=		和 ={motion} 类似，过滤高亮行。{Vi 无此功能}


						*tempfile* *setuid*
Vim 使用临时文件来处理过滤、执行比较和用于 tempname()。Unix 上，该文件会放在一
个私人的目录里 (只能被当前用户访问)，以防堵安全上的漏洞 (例如，符号链接攻击或
文件被其他用户读取等)。Vim 退出时，自动删除该目录及之下的所有文件。如果 Vim 本
身设置了 setuid 位，这样或许会有问题。临时文件由 setuid 用户拥有，但过滤程序以
原来用户的权限执行。
MS-DOS 和 OS/2 上，使用以下目录中首个可用者: $TMP、$TEMP、c:\TMP、c:\TEMP。
Unix 上，使用的目录依次为: $TMPDIR、/tmp、当前目录、$HOME。
MS-Windows 上，使用 GetTempFileName() 系统函数。
其它系统上使用 tmpnam() 库函数。


4.2 替代						*:substitute*
							*:s* *:su*
:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]
			对 [range] 指定的行把 {pattern} 的匹配替代成
			{string}。
			关于 {pattern}，参见 |pattern|。
			{string} 可以是按字面意义的，也可以包含特殊字符。
			参见 |sub-replace-special|。
			如果不指定 [range] 和 [count]，仅在当前行进行替代。
			如果指定 [count]，在 [range] 最后一行开始的 [count]
			行进行替代。如果不指定 [range] ，则从当前行开始。
			另见 |cmdline-ranges|。
			关于 [flags]，参见 |:s_flags|。

:[range]s[ubstitute] [flags] [count]
:[range]&[&][flags] [count]					*:&*
			使用最后一次 :substitute 相同的模式和替代字符串，但不
			包括相同的标志位。你可以另加 [flags] (见 |:s_flags|)。
			注意 在 ":substitute" 之后，不能使用 '&' 标志位。它被
			认为是一个模式分隔符。
			":substitute" 和 'c'、'g' 和 'r' 标志位之间的空格不是
			必需的，但在脚本里为了避免混淆起见，最好保留它。

:[range]~[&][flags] [count]					*:~*
			使用最后一次 :substitute 相同的替代字符串，但使用最近
			使用的搜索模式作为匹配模式。这类似于 ":&r"。
			关于 [flags]，参见 |: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 无此功能}

[n]	报告匹配的次数，并不实际进行替代。忽略 [c] 标志位。匹配报告的发生就像
	'report' 总是为零那样。可用于 |count-items|。

[p]	显示包含最后一次替代的行。

[#]	类似 [p]，且在前面加上行号。

[l]	类似 [p]，但显示的方式类似于 |:list|。

[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)。你可以用别的命令或 |\v|
之类。原因是标志位只能在跳过模式之后才能找到，而要跳过模式，必须先知道模式的
"魔术性"。第二十二条军规！

如果 substitute 命令所用的 {pattern} 为空，该命令使用上次的 substitute 或者
":global" 命令用过的模式。如果有 [r] 标志位，该命令使用上次 substitute、
":global" 或者搜索命令使用的模式。

如果 {string} 省略，替代命令假定它为空。这样就把匹配文本删除了。这时，
{pattern} 之后的分隔符也可省略。例如: >
	:%s/TESTING
删除所有行上的 "TESTING"，但每行只删一个。

为了和 Vi 的兼容性，有两个例外:
"\/{string}/" 和 "\?{string}?" 等同于 "//{string}/r"。
"\&{string}&" 等同于 "//{string}/"。
							*E146*
除了用 '/' 来包围模式和替代字符串之外，你可以使用任何其他的单字节字符，除了
字母、数字、'\'、'"' 或 '|' 之外。这可以用于 '/' 是搜索模式或替代字符串一部
分的场合。例如: >
	:s+/+//+

关于模式的定义，参见 |pattern|。在可视列块模式下，如果模式中使用了 |/\%V|，那
么替代只在列块内进行，否则它作用于整行。

					*sub-replace-special* *:s\=*
{string} 以 "\=" 开始时，它被作为表达式来执行，参见 |sub-replace-expression|。
你可以在这里使用任何特殊字符。否则，{string} 字符串里的字符有如下的特殊含义:
								*:s%*
如果 {string} 等于 "%"，且 'cpoptions' 选项包含 '/'，重复使用上次替代命令的
{string}。|cpo-/|

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"
  :s/\w\+/\u\0/g		 修改 "bla bla"  为 "Bla Bla"

注意: 在以前的版本里，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*
						*sub-replace-\=*
当替代字符串以 "\=" 开始时，其余部分被解释为一个表达式。该功能不能递归调用。出
现在该表达式里面的 substitute() 函数不能使用 "\=" 作为替代字符串。

除了 "<CR>"、"\<CR>" 和 "\\" 以外，|sub-replace-special| 提到的字符的特殊含义
这里不适用。这样，表达式里应出现的反斜杠须加倍出现，要插入的 <CR> 之前要加上反
斜杠，如果你想分行，则使用不带反斜杠的 <CR>。

为了方便起见，<NL> 字符也被用作换行符。在这之前加上反斜杠得到一个真正的 <NL>
字符 (在文件里成为 NUL)。

如果结果是 |List|，连接其中的项目并以换行符分隔。这样，每个项目单独成为一行，
当然本身就包含换行符的除外。

完整的匹配可以用 "submatch(0)" 得到。首个括号里的匹配可以用 "submatch(1)"，余
者类似。

小心: 分隔符不能出现在表达式里！可以考虑使用 "@" 或者 ":" 那样的字符。执行结果
里出现分隔符不成问题。

例如: >
	:s@\n@\="\r" . expand("$HOME") . "\r"@
把换行符替代为包含 $HOME 值的一个新行。 >

	s/E/\="\<Char-0x20ac>"/g
把所有的 'E' 字符替代为欧元符号。详见 |<Char->|。


4.3 搜索与替代						*search-replace*

							*:pro* *:promptfind*
:promptf[ind] [string]
			弹出搜索对话框。如果给出 [string]，它被用作初始的搜索
			字符串。
			{仅适用于 Win32、Motif 和 GTK GUI 环境}

						*:promptr* *:promptrepl*
:promptr[epl] [string]
			弹出搜索/替代对话框。如果给出 [string]，它被用作初始的
			搜索字符串。
			{仅适用于 Win32、Motif 和 GTK GUI 环境}

4.4 改变制表						*change-tabs*
							*: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]		显示所有编号和命名寄存器的内容。但不列出用于 |:redir| 
			目的地的寄存器。
			{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 试图把选择的文本替换成寄
存器的内容。是否工作如你所愿决定于选择的类型和寄存器里文本的类型。对于列块选择
而言，它也决定于列块的大小，和头尾是否在已存在的字符上。(实现细节: 实际上，它
先把寄存器的内容放到选择区之后，再删除选择区的内容。)
前次选择的文本被放在无名寄存器中。如果希望把相同的文本重复放入可视选择区多次，
请选用其它寄存器。例如，先抽出要复制的文本，再可视化选择要替换的文本，然后使用
"0p。重复任意多次均可，而每次无名寄存器都会被改变。

							*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 只有在你指定的时候才使用这些寄存器。指定为小写字母时替换原来的内容，指定为
大写字母时附加到原来的内容。如果 'cpoptions' 里有 '>' 标志位，在附加文本前插入
一个换行符。


5. 只读寄存器 ":、".、"% 和 "#
它们是 '%'、'#'、':' 和 '.'。你只能在 "p"、"P"、":put" 命令和 CTRL-R 的时候使
用它们。{Vi 无此功能}
						*quote_.* *quote.* *E29*
	".	包含最近插入的文本 (和插入模式命令 CTRL-A 和 CTRL-@ 插入的一
		样)。注意: 它不适用于 CTRL-R 在命令行上的操作。它的工作方式稍
		有不同，例如，文本是被插入而不是放置的 ('textwidth' 和其它选项
		影响插入的内容)。
							*quote_%* *quote%*
	"%	包含当前文件名。
							*quote_#* *quote#*
	"#	包含轮换文件名。
						*quote_:* *quote:* *E30*
	":	包含最近执行过的命令行。例如: 用 "@:" 重复上次执行过的命令行命
		令。只有当一个命令行中至少一个字符是键入的，该寄存器才会保存命
		令行的内容。所以，如果命令行完全来自映射，该寄存器保持不变。
		{仅当编译时加入 |+cmdline_hist| 特性才有效}

6. 表达式寄存器 "=				*quote_=* *quote=* *@=*
其实并没有这么一个寄存器可以储存文本，但是这是用来在使用寄存器的命令中使用表达
式的一个方式。表达式寄存器是只读的，你不能把文本放置其中。在 '=' 之后，光标移
到命令行上，这时你可以输入任何的表达式 (见 |expression|)。所有普通的命令行编辑
命令都可以使用，还有一个表达式专门的历史表。当你按回车结束命令行时，Vim 计算表
达式的结果。如果你用 <Esc> 结束，Vim 终止表达式。如果你不输入表达式，Vim 使用
最近的表达式 (和 "/" 命令的处理相似)。

表达式的计算结果必须是一个字符串。数值结果会自动转化为字符串。对 "p" 和 ":put"
命令而言，浮点数结果也会被转化为字符串。如果结果为列表，每个成员被转成字符串，
然后被单独放在一行上。字典、函数引用类型的结果则产生错误信息 (通过 string() 转
化)。

如果 "= 寄存器被 "p" 命令使用，该字符串会在 <NL> 字符处断开。如果该字符串以
<NL> 结尾，则它被视为一个面向行的寄存器。{Vi 无此功能}

7. 选择和拖放寄存器 "*、"+ 和 "~ 
用这些寄存器来保存和取得 GUI 界面选择的文本。参见 |quotestar| 和 |quoteplus|。
如果剪贴板不存在或者不工作，使用无名寄存器。Unix 上，仅当 |+xterm_clipboard|
特性存在时剪贴板才可用。{Vi 无此功能}

注意 "* 和 "+ 在 X11 系统上有分别。关于该差别的解释，参见 |x11-selection|。在
MS-Windows 上，"* 和 "+ 的使用实际上是等价的，可见 |gui-clipboard|。

						*quote_~* *quote~* *<Drop>*
只读的 "~ 寄存器保存最近一次拖放操作放下的文本。如果有什么东西被放到 Vim 上，
"~ 寄存器被填充，<Drop> 虚拟键被激活。如果你需要，你可以重定义该键的映射；缺省
的动作 (适用于所有模式) 是把 "~ 寄存器的内容插入到当前光标位置。{Vi 无此功能}
{仅当编译时加入 |+dnd| 特性才有效，当前只适用于 GTK GUI 版本}

注意: "~ 寄存器仅用于在 Vim 上拖放普通文本。拖放 URI 列表在内部处理。

8. 黑洞寄存器 "_				*quote_*
当写到这个寄存器时，什么都不会发生。这可以用来删除文本，而不影响任何正常的寄存
器。从该寄存器读时，什么都不会返回。{Vi 无此功能}

9. 最近搜索模式寄存器	"/			*quote_/* *quote/*
含有最近搜索的模式。它被 "n" 和 'hlsearch' 使用。可以用 ":let" 来修改。你可以
改变它使得 'hlsearch' 不经过实际的搜索直接高亮某些匹配。你不能把抽出或者删除命
令的内容放到该寄存器上。搜索方向则可从 |v:searchforward| 得到。
注意 从函数返回时该值被复原 |function-search-undo|。
{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} 动作跨越的行进行排版。
			排版使用如下三种方式之一:
			1. 如果 'formatexpr' 不为空，计算该表达式。每个缓冲区
			   的值可以不同。
			2. 如果 'formatprg' 不为空，使用外部程序。
			3. 否则，使用内部排版机制。

			第三种方式使用 'textwidth' 选项控制所有待排版行的行宽
			(见下)。
			如果 'textwidth' 选项为 0，则排版行宽设为屏幕的宽度
			(但最大宽度不超过 79)。
			'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' 和 'formatexpr'
			选项。
			{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' 选项。

你可以设置 'formatexpr' 选项为某表达式或设置 'formatprg' 选项为外部程序名，Vim
会用之进行文本排版。'textwidth' 等选项对外部程序的排版不起作用。

							*right-justify*
Vim 没有靠右控制对齐 (right justify) 文本的命令。你可以用 "par" 这样的外部命令
来实现 (例如， "!}par" 对到段落尾的文本排版)，或者设置 'formatprg' 为 "par"。

							*format-comments*
用户手册的 |30.6| 一节给出注释排版的总览。

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	右对齐。同上，不过不是最左字符而是最右字符。详情见下。

  O	"O" 命令不把它当作注释。

  x	允许三段式注释用以下方式结束: 在中间字符串自动提供的情况下，在新行第一
	个动作是输入结尾字符串的最后一个字符。详情见下。

  {digits}
	在和 's' 或 'e' 一起使用时: 对自动插入的中间或结尾字符串增加 {digit}
	单位的位移。该位移以左对齐的位置为基准。详情见下。

  -{digits}
	和 {digits} 类似，但减少缩进。这只对开始或结尾部分至少有相当数量的缩进
	时才有效。

如果一个字符串没有 'f'、's'、'm' 或 'e' 任何一个标志位，Vim 假设注释字符串在每
行都重复出现。标志位部分可以为空。

在 {string} 之前或之后的任何空白都是 {string} 的一部分，所以不要随便留出开头或
结尾的空白，除非空白的确是注释字符串的一部分。

如果某个注释字符串是另一个字符串的一部分，先指定完整的，再指定部分的。例如，要
包含 "-" 和 "->"，用 >
	:set comments=f:->,f:-

三段式注释必须以开始、中间和结尾三部分给出，而且不能间杂其它的部分。一个三段式
C 注释的例子是 >
	sr:/*,mb:*,ex:*/
为了避免形如 "*ptr" 的内容被识别为注释，这里的中间字符串包含了 'b' 标志位。对
三段式注释而言，Vim 从开始和中间字符串之后查找结尾字符串。如果找到，注释就不会
再从下一行继续。三段式注释必须要有一个中间字符串，不然 Vim 无法识别中间的那些
行。

注意 上述三段式注释定义里的 "x" 标志位。当你在一个 C-注释里按回车时，Vim 会自
动在新行后插入中间字符串: " * "。要结束注释，你只需要在新行里首先键入 "/"。这
样就把中间字符串替换成结尾字符串并应用指定的对齐方式，成为了 " */"。从而省却了
先按退格键的麻烦。


这里是一个关于用于对齐的标志位的例子，使得注释看起来很突出 (也很像一个 1 字)。
考虑注释字符串 >
	sr:/***,m:**,ex2:******/

                                   /***
                                     **<--右对齐，来自 "r" 标志位
                                     **
  2 个单位的位移，来自 "2" 标志位--->**
                                   ******/
该例中，第一行注释是键入的，然后按回车四次，最后按 "/" 以结束注释。

这里是三部分注释的一些细节。有三个时间点应用对齐和位移标志位: 输入起始字符串后
开启新行、在结尾字符串前开启新行、三部分注释的自动结束。而结尾部分的对齐标志位
要反过来看；这样，相同的对齐标志位在分别用于 "s" 和 "e" 时才会使起始和结尾部分
有相同的缩进。每个注释部分只应用一种对齐方式，但位移优先于 "r" 和 "l" 标志位。

打开 'cindent' 在很多情况下会覆盖对齐标志位。使用其它方法，如 |gq| 或 |=| 来重
新缩进也不会参考对齐标志位。这些其它的排版选择可以定义类似的行为。一个担心是
'cindent' 虽然有众多附加的选项来对注释进行基于上下文的缩进，但不能再现三部分注
释的缩进对齐。但 'indentexpr' 应该有能力很好地处理三部分注释。

其它示例: >
   "b:*"	包含 "*" 开头的行，但 "*" 后面不是空白的除外。这样避免指针取值
		操作 "*str" 被识别为注释。
   "n:>"	包含形如 ">"、">>"、">>>" 等开头的行。
   "fb:-"	包含 "- " 开头的列表，可用来自动排版。

该选项的缺省值是 "b:#"。这意味着 "#include" 开头的行不会被认为是注释，但
"# define" 是。这是个不得不然的妥协。

{仅当编译时加入 |+comments| 特性才有效}

							*fo-table*
你可以使用 'formatoptions' 选项来控制 Vim 如何对文本进行排版。'formatoptions'
是一个字符串，它可以包含下列字符。缺省设置是 "tcq"。为了提高可读性，你可以用逗
号分隔选项字符。

字符	 在 'formatoptions' 里代表的含义   ~

t	使用 'textwidth' 自动回绕文本
c	使用 'textwidth' 自动回绕注释，自动插入当前注释前导符。
r	在插入模式按回车时，自动插入当前注释前导符。
o	在普通模式按 'o' 或者 'O' 时，自动插入当前注释前导符。
q	允许 "gq" 排版时排版注释。
	注意 排版不会影响空行或者只有注释前导符的行。这样的行开启一个新段落，
	注释前导符的改变也是如此。
w	拖尾的空格指示下一行继续同一个段落。而以非空白字符结束的行结束一个段
	落。
a	自动排版段落。每当文本被插入或者删除时，段落都会自动进行排版。参见
	|auto-format|。
	如果 'c' 标志位存在，该设置只对识别的注释有效。
n	在对文本排版时，识别编号的列表。实际上，这里使用了 'formatlistpat' 选
	项，所以可以使用任何类型的列表。出现在数字之后的文本缩进距离被应用到后
	面的行。数字之后可以有可选的 '.'、 ':'、')'、']' 或者 '}'。
	注意 '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' 选项
自动插入注释前导符)。但 'a' 标志位存在时有例外。|auto-format|

注意 如果 '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' 标志位。可用于源代码。

- 设置 'textwidth' 为你希望的宽度。如果为零，使用 79 或屏幕宽度中较小的那个。

还有一些警告:

- 如果段落没有正确分隔，任何改变都会使得所有相连的文本自动排版。考虑 >

	:set fo-=a

- 如果用 'w' 标志位 (行尾的空格意味着段落的继续) 并且用 |dd| 删除了段落的末
  行，这段落自动和下一个段落合并为一个段落。

- 改变的文本被保存以备可能的撤销之用。排版也是改变的一种。所以每次排版都会为撤
  销保存文本。这会有相当的内存开销。

- 排版一个很长的段落和/或复杂的缩进也许会相当慢。

==============================================================================
7. 文本排序						*sorting*

Vim 有排序函数和排序命令。排序函数可见: |sort()|。

							*:sor* *:sort*
:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
			给 [range] 里的行排序。如果没有给出行范围，给所有行排
			序。

			带 [!] 则反向排序。

			带 [i] 则忽略大小写。

			带 [n] 则排序基于每行的第一个十进制数 (在 {pattern} 匹
			配之后或之内)。
			数值包含前导的 '-'。

			带 [x] 则排序基于每行的第一个十六进制数 (在 {pattern}
			匹配之后或之内)。忽略引导的 "0x" 或 "0X"。
			数值包含前导的 '-'。

			带 [o] 则排序基于每行的第一个八进制数 (在 {pattern} 匹
			配之后或之内)。

			带 [u] 则只保留完全相同的行的第一行 (如果带 [i]，忽略
			大小写的区别)。
			没有这个标志位，完全相同的行的序列会按照它们原来的顺序
			被保留下来。
			注意 引导和拖尾的空白差异会导致不相同的行。

			如果指定 /{pattern}/ 并且没有 [r] 标志位，跳过匹配
			{pattern} 的文本，使得排序在匹配之后的内容上进行。
			除了斜杠以外，任何非字母的字符都可以。
			例如，要按第二个逗号分隔的字段排序: >
				:sort /[^,]*,/
<			按虚拟第 10 列的文本排序 (从而忽略制表和空格的区别): >
				:sort /.*\%10v/
<			按每行的第一个数值排序，不管它前面有什么: >
				:sort /.\{-}\ze\d/
<			(说明: ".\{-}" 匹配任何文本，"\ze" 设置匹配结束位置，
			\d 匹配单个数位。)
			带 [r] 则排序在匹配 {pattern} 的文本上进行，而不是如上
			所述的用它之后的文本。
			例如，要按每行的前三个字母排序且只看这三个字母: >
				:sort /\a\a\a/ r

<			如果使用 {pattern}，不匹配 {pattern} 的行按照它们原来
			的顺序被保留，但和匹配 {pattern} 的行分开。如果反向排
			序，它们会以反向顺序出现，并在排序好的行之后。否则它们
			会以原有顺序出现，在排序好的行之前。

			如果 {pattern} 为空 (例如指定 //)，则使用最近使用的搜
			索模式。这样你可以先试好模式，然后在执行。

注意 ":sort" 和 ":global" 一起使用并不能对匹配的行进行排序，这样做没有意义。

排序的细节取决于使用的库函数。不能保证它是 "稳定" 排序，也不能保证排序依赖于当
前的 locale。你要自己试试才知道。

排序可以被中断,但在整个过程里如果中断得太晚，最后可能会出现重复的行。这取决于
使用的系统库函数。

 vim:tw=78:ts=8:ft=help:norl:
