撤销在vim中打开缓冲区以来的所有更改

59

如何撤销打开缓冲区以来的所有更改?我想可能会有一些类似于:earlier的命令可以实现这个功能。

更新:许多人建议通过遍历先前的文件写入解决问题。这不是我所要求的。我想要返回到最初加载到缓冲区的文件的原始状态,无论此后进行了多少次写入。

7个回答

90

要将当前缓冲区还原为撤销列表中记录的第一次更改之前的原始状态(参见:help undo-tree),可以使用以下连续两个调用:undo命令:

:u1|u

第一个命令(:undo 1)将回滚到缓冲区在第一次注册更改后的状态, 而第二个命令(:undo)则回滚到第一次更改本身。

从版本8.1开始(参见:helpg Patch 8.0.1441),Vim接受编号为0的更改作为:undo命令的有效参数,最终提供了一种引用到任何注册更改之前状态的方法。这使得可以通过单个命令调用来实现相同的效果:

:u0

1
请问您能否解释一下这是如何工作的?我在帮助文档中找不到有关如何使用此管道语法与undo-tree的信息。 - David Rivers
+1,对于我认为与benpmorgan提供的基本相同的解决方案而言,这是更简洁的版本。谢谢! - David Rivers
3
是的,这应该与我之前使用的 :u 1 相同;如果没有任何更改,它将会给出一个错误提示“找不到撤销编号1”(使用 :earlier 和大计数可以解决这个问题)。管道语法不是撤销树的一部分;它只是将两个 Vim 命令依次执行。(即等同于 :u1,然后是 :u)。 - benpmorgan
9
@David: |字符用于分隔单行命令,不像shell管道。上面的命令首先运行:undo 1命令,然后运行:undo命令。前者会跳转到第一次更改之后,而后者会撤消第一次更改,将当前缓冲区恢复到没有记忆更改之前的状态。 - ib.
1
@ib:有时候那个错误可能会有用,但只有在从未进行任何更改的情况下才会出现。如果进行了一次更改,然后撤消了它(因此我们回到了干净的状态),u1 | u将重做更改,然后撤消它,因此它不会给出错误(它还会提供两个状态行)。如果您使用10000000g-,则如果处于完全撤消状态(我认为这更有用),它将说“已经是最旧的更改”,如果有要撤消的更改,则仅会给出一个状态行。 - benpmorgan
显示剩余7条评论

59

You can use the

:edit!

获取最早保存状态的命令。更多信息请参见:help edit!

您还可以查看像gundo.vim这样的内容(可在此处找到),它以图形方式显示整个撤消树,您可以轻松地在各个点之间跳转。然后是histwin插件,我尚未使用过,但提供类似的功能。


14
请注意,:e! 命令会放弃最近一次文件写入后所做的任何更改,而不是自打开缓冲区以来所做的所有编辑。 - ib.
@ib:确切地说,这不是我想要的。 - David Rivers

13

在 vim 8.1+ 和 neovim 中,你只需使用 :u0 命令即可。


1
你能详细解释一下并说明它如何解决这个问题吗? - yass
1
目前为止,我还没有找到该功能的文档。只是注意到在这种情况下使用 [count] 为 0 会撤销所有更改,包括最早的更改,并且再次输入 :u 将会显示“已经回到最早的更改”消息。 - Hope
2
适用于现代GNU vim Vi IMproved 8.1,编译日期为2018年8月17日。 - Tony Barganski
谢谢!看来我落后了很多! - David Rivers

6

来自文档:

:u[ndo] {N} 跳转到更改编号为{N}之后。有关{N}的含义,请参见|undo-branches|。 {不适用于Vi}

如果您键入:u 1,则似乎会跳转到第一个更改之后;按u或键入:u然后将返回更改。

否则,您可以使用非常大的计数器进行:earlierg-, 例如:earlier 100000000100000000g-

如果您将其放入映射/命令中,则可以轻松执行任何操作。 例如:

:nnoremap <C-F12> :earlier 100000000<CR>


我仍在努力理解正在发生的事情。我可能需要阅读另一个有关撤销分支的教程。 - David Rivers

3
为了访问之前保存的文件状态,我认为以下操作是可行的::earlier 1f。根据文档说明:
 :earlier {N}f      Go to older text state {N} file writes before.
                When changes were made since the last write
                ":earlier 1f" will revert the text to the state when
                it was written.  Otherwise it will go to the write
                before that.
                When at the state of the first file write, or when
                the file was not written, ":earlier 1f" will go to
                before the first change.

谢谢,但我想返回文件最初加载到缓冲区时的原始状态,无论此后进行了多少次写操作。 - David Rivers

1
一个图形化的解决方案:
Gundo插件允许在撤销历史记录中进行可视化比较。
打开Gundo的“撤销历史记录窗格”,输入G并跳转到最后一行,然后我们就可以返回到原始文件。

0
:earlier {N}m Go to older text state about {N} minutes before.

那应该有所帮助…并且你还有 {N} 小时之前。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接