UNDO

*undo.txt*      For Vim version 7.1.   最后更改:2006.07.26


		     Vim 参考手册    作者:Bram Moolenaar
			(译者: jwdu, tocer http://vimcdoc.sf.net)

撤销和重做							*undo-redo*

在用户手册的 |02.5| 节对它们的基本操作有解释。

1. 撤销和重做操作的命令		|undo-commands|
2. 撤销操作的两种方法		|undo-two-ways|
3. 撤销块			|undo-blocks|
4. 撤销分支			|undo-branches|
5. 撤销操作的解释		|undo-remarks|


1. 撤销和重做命令					*undo-commands*

<Undo>*undo* *<Undo>* *u*
u			撤销 [count] 次更改。 		{Vi: 仅有一级}

							*:u* *:un* *:undo*
:u[ndo]			撤销一次更改。  		{Vi: 仅有一级}

:u[ndo] {N}		转到改变号 {N} 之后。{N} 的含义参见 |undo-branches|。
			{Vi 无此功能}

							*CTRL-R*
CTRL-R			重做 [count] 次被撤销的更改。	{Vi: 刷新屏幕}

							*:red* *:redo* *redo*
:red[o]			重做一个被撤销的更改。		{Vi: 没有 redo}

							*U*
U			撤销最近对特定行所作的一系列更改。
			{Vi: 仅当这些修改不超出该行的范围}

由于最近所作的更改是被记住的,因此,你可以应用上面的撤销和重做命令把文件倒转到
你所作每次更改以前的状态。当然,你也可以重新应用这些修改,把文件重做到执行撤销
操作以前的状态。

对于撤销/重做 (undo/redo) 来说,"U" 命令和其他命令是同等对待的。所以 "u" 可以
撤销一个 "U" 命令、'CTRL-R' 也可以重做对 "U" 命令的撤销。当 "U"、"u" 和
'CTRL-R' 三个命令混合使用时,你将注意到 "U" 命令决意将被该行还原到前一个 "U"
命令之前的状态。这或许会令你困惑。多试试,你会习惯的。
"U" 命令总是把缓冲区标记为已改变。即使它把修改过的缓冲区重做到未改变的状态也是
如此。为此,只有使用 "u" 命令,才能令缓冲区正确地回复到未改变的标记。


2. 撤销操作的两种方法					*undo-two-ways*

撤销和重做的工作模式依赖于 'cpoptions' 中 'u' 标志位。这里有两种模式,Vim 模式
(不包含 'u') 和 Vi-兼容模式 (包含 'u')。在 Vim 模式下,"uu" 命令撤销两次改变,
在 Vi-兼容模式下,"uu" 命令什么也不做 (撤销第一次撤销)。

不包含 'u' 的 Vim 模式:
及时的撤销命令可以回到先前的状态。你也可以使用重做命令再次前进。不过,如果在撤
销命令后你做了一个新的改变,重做上次的撤销便不再可能。

包含 'u' 的 Vi-兼容模式:
撤销命令撤销包含以前的撤销命令在内的任何更改。重做命令重复前一个撤销命令。但它
_不_用来重复改变命令。为此请用 "." 命令。

举例		Vim 模式		Vi-兼容模式	
"uu"		两次撤销		空操作
"u CTRL-R"	空操作			两次撤销

原理:	Nvi 使用 "." 命令而不是 CTRL-R。不幸的是,这不是 Vi 兼容的。例如
	"dwdwu." 命令,在 Vi 中删除两个词,但在 Nvi 中,它什么也不做。


3. 撤销块						*undo-blocks*

单个 undo 命令通常撤掉一个输入的命令,不论这个命令造成多少改变。这个可以撤销的
改变序列构成了一个撤销块。所以如果键入的命令调用一个函数,那么在这个函数中的所
有命令全部被撤销。

如果你想编写一个函数或脚本,它不包含新的可撤销之改变,而合并到之前的改变中,用
以下命令:

						*:undoj* *:undojoin* *E790*
:undoj[oin]		把其后的改变和以前的撤销块进行合并。
			警告: 小心使用。它会阻止用户合理地撤销改变。不要在撤销
			或重做后使用。
			{Vi 无此功能}

这最适用于在改变的过程中需要提示用户的场合。例如调用 |getchar()| 的函数。确保
在这之前有一个相关的必须与之合并的改变。

这条命令不能单独工作,因为下一个键击会再次造成新改变。但你可以这么做:

	:undojoin | delete

在此之后,"u" 命令会同时撤销 delete 命令和前一次改变。


4. 撤销分支					*undo-branches* *undo-tree*

上面我们只讨论了单线的撤销/重做。但你也可以进行分支。考虑你先撤销了若干改变,
然后又进行了一些其它的改变。此时,被撤销的改变就成为一个分支。下面的命令使你能
够到达那个分支。

这在用户手册中有解释: |usr_32.txt|。

							*:undol* *:undolist*
:undol[ist]		列出改变树的所有叶结点。例如:
				number changes   time 
				4      10	 10:34:11
				18     4	 11:01:46

			"number" 列是改变号。这个编号持续增加,用于标识特定可
			撤销的改变,参见 |:undo|。
			"changes" 列是树的根结点到此叶结点所需的改变数目。
			"time" 列是此改变发生的时间。

							*g-*
g-			转到较早的文本状态。如果带计数,重复那么多次。
			{Vi 无此功能}
							*:ea* *:earlier*
:earlier {count}	转到 {count} 次较早的文本状态。
:earlier {N}s		转到大约 {N} 秒钟之前的较早的文本状态。
:earlier {N}m		转到大约 {N} 分钟之前的较早的文本状态。
:earlier {N}h		转到大约 {N} 小时之前的较早的文本状态。

							*g+*
g+			转到较新的文本状态。如果带计数,重复那么多次。
			{Vi 无此功能}
							*:lat* *:later*
:earlier {count}	转到 {count} 次较新的文本状态。
:earlier {N}s		转到大约 {N} 秒钟之后的较新的文本状态。
:earlier {N}m		转到大约 {N} 分钟之后的较新的文本状态。
:earlier {N}h		转到大约 {N} 小时之后的较新的文本状态。


注意 如果由于 'undolevels' 选项,撤销信息被清空,那么文本状态将无法访问。

在不同时间点上移动的时候,不要奇怪一个时间点会同时发生多个改变。通过撤销树跳转
然后又做了新的改变后就会发生这种情况。

示 例

从这一行开始:
	one two three 

按三次 "x" 删除第一个单词:
	ne two three 
	e two three 
	 two three 

现在按 "u" 三次撤销:
	e two three 
	ne two three 
	one two three 

按三次 "x" 删除第二个单词:
	one wo three 
	one o three 
	one  three 

现在按 "g-" 三次撤销:
	one o three 
	one wo three 
	 two three 

现在,回到第一个撤销分支,也就是在删除 "one" 之后。重复 "g-" 会回到原始文本:
	e two three 
	ne two three 
	one two three 

使用 ":later 1h" 跳到最后一次改变:
	one  three 

使用 ":earlier 1h" 再次回到开始:
	one two three 


注意 使用 "u" 和 CTRL-R 无法得到全部可能的文本状态,但是重复 "g-" 和 "g+" 却可
以。


5. 撤销操作的解释					*undo-remarks*

能记忆的最大改变次数由 'undolevels' 选项决定。如果它的值是零,我们总是运行在
Vi-兼容模式。如果它的值是负的,任何撤销都是不可能的。这只有在内存紧张的时候适
用。

当前缓冲区的位置标记 ('a 至 'z) 随文本一起被保存和复原。{Vi 的做法稍有不同}

当所有的改变都被撤销时,缓冲区被标记为未改变。这时可以使用 ":q" 而不一定是
":q!" 退出 Vim 。{Vi 并非如此} 注意未改变是相对文件的最后写入而言的。在写入
":w" 后紧跟的撤销 "u",实际上改变了被写入以后缓冲区的状态。因此,此时缓冲区应
被视为已改变。

当使用手动 |folding| 时,折叠不会被保存和复原。只有完全发生折叠内部的改变才不
会影响该折叠,因为它开头和最后一行没有改变。

数字编号的寄存器也可以被用作撤销删除操作。你每一次删除文本,该文本被放在 "1 寄
存器中。同样的,"1 寄存器的内容被移到 "2 寄存器,依次类推。"9 寄存器的内容则会
丢失。现在,你可以通过命令 '"1P' 得到最近删除的文本。(如果被删除的内容来自最近
的删除或复制操作,'P' 或 'p' 同样也可得到你要的结果,因为他们会复制未命名寄存
器的内容)。使用 '"3P' 可以得到三个删除操作之前的文本。

							*redo-register*
如果你想得到多于一处被删除文本的内容,你可以使用重复命令 "." 一个特殊的特性:
它会递增所使用寄存器内的序号。所以,你如果先使用 ""1P" ,那么接下来的 "." 就意
味着 '"2P 。重复这样的操作,所有编号的寄存器都会被插入。

例如: 如果你用 'dd....' 删除了内容 (五行文本),那么用 '"1P....' 可以恢复之。

如果你不知道被删除的内容在哪一个寄存器,你可以用 |:display| 命令。还有一个方法
就是先试第一个寄存器 '"1P' ,如果不对,用 'u.' 命令。这将会移走第一次放进的内
容,然后在第二个寄存器上重复 put 命令。重复使用 'u.' 直到你得到想要的内容为
止。

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

Generated by vim2html on 2008年 03月 27日 星期四 17:04:45 CST