【问题标题】:How is the undo tree used in Vim?Vim 中如何使用撤销树?
【发布时间】:2010-11-08 12:00:14
【问题描述】:

This answer 说:

Vim 的撤消/重做系统是无与伦比的。键入一些内容,撤消,键入其他内容,您仍然可以取回您键入的第一个内容,因为 Vim 使用的是撤消树而不是堆栈。在几乎所有其他程序中,您输入的第一件事的历史都会在这种情况下丢失。

这是我第一次听说这个。如何沿着树回溯?

【问题讨论】:

标签: vim undo


【解决方案1】:

这个页面解释了你需要知道的一切:

http://vimdoc.sourceforge.net/htmldoc/usr_32.html

【讨论】:

    【解决方案2】:

    另请参阅:h undo-redo,其中列出了所有命令及其用法。

    有两种方法可以遍历撤消树。一是“回到过去”。 g+g- 将按时间顺序或逆时间顺序遍历树中的所有节点(这可能有点令人困惑,因为它可以在撤消分支之间任意跳转,但如果您执行 g- 足够长的时间,您'总会到达你最终需要去的地方)。 :earlier:later 使用时间描述符,例如 7m1h;再次,这可以在撤消分支之间任意跳转。

    另一种方法是使用:undo n 跳转到树中的特定节点,其中n 是一个动作的编号。 (所有操作,即文本添加、删除、替换,都按顺序编号。)您可以通过:undolist 查找撤消树的叶子上的操作数。这将使您轻松地在分支之间跳跃。然后,您可以使用 uCtrl-R 上下移动该分支。

    Vim 帮助中有一些很好的例子。弄清楚它是如何工作的最好方法是稍微玩一下。

    【讨论】:

    • 你能合并分支吗? (我在开玩笑)
    • 有点。查找:h undojoin
    • Vim 太棒了,它甚至实现了我们开玩笑说它有多棒的方式!
    • 我不知道如何使用这个撤销树,但我知道它总有一天会挽救我的生命。嗯,这一天来了。谢谢!!
    • @Pod 貌似undojoin跟分支没有关系;事实上,下一个帮助部分以“上面我们只讨论了一行撤消/重做。但也可以分支”开头。有什么方法可以将undojoin 与我没有看到的分支一起使用?
    【解决方案3】:

    如果您使用的是 vim,您可以使用以下命令浏览撤消树:

    • u:(撤消)在撤消树中移回
    • Ctrl+R:(重做)在撤消树中前进

    及时返回或转发文档的其他方式:

    • :earlier 15m:时光倒流15分钟
    • :later 15m: 前移15分钟

    【讨论】:

    • 这个答案只解释了如何在一个分支上向前和向后移动。不是如何在分支之间移动。
    • 这将在所有分支中移动,按时间顺序对所有点进行排序。请参阅@BrianCarper 的回答。
    • @JonathanHartley,如果您使用的是earlierlater,它不会跨分支移动。我希望大多数人并不真正关心或记住他们创建的各种分支。但只想回到过去。如果您想创建分支并将它们命名为 git 或版本控制系统是更好的选择。
    • @alpha_989 你关于版本控制的 cmets 没有意义。版本控制是针对磁盘上命名文件的状态。我们谈论的是 Vim 的撤消树,它只是内存中的数据结构。他们都使用“分支”这个词,但意思不同。
    • 感谢大家指出早/晚跨分支移动!
    【解决方案4】:

    我参加聚会有点晚了,
    但我想我会提到我为 Vim 编写了一个撤消树可视化插件:
    https://github.com/sjl/gundo.vim

    就个人而言,我发现像这样绘制树是我理解它的唯一方法。

    【讨论】:

    • github.com/sjl/gundo.vim 上存在一个更新的 git 存储库。使用 vim-plug,可以使用Plug 'sjl/gundo.vim'nnoremap <F5> :GundoToggle<CR> 安装插件(用您要绑定的任何键序列替换<F5>
    【解决方案5】:

    【讨论】:

      【解决方案6】:

      除了使用 gundo.vim 我还想提一下 g+g-

      【讨论】:

        【解决方案7】:

        我知道这个问题已经得到解答,但我想我会添加一个示例。

        创建一个新文件并输入:

        this is a line
        

        undol 将显示撤消树。此时您还没有撤消任何操作

        :undol
        
        number changes  when               saved
             1       1  14:50:36
        

        现在按 ESC 并将该行修改为:

        this is a old line
        

        切换到正常模式并按 u(撤消),这应该会删除“旧”。如果你检查undol,此时你仍然只有一个分支。

        现在修改该行,使其显示:

        this is a new line
        

        现在:undol 显示:

        number changes  when               saved
             2       2  87 seconds ago
             3       2  3 seconds ago
        

        你可以通过输入切换到第一个分支

        :u 2
        

        这会将您移动到与编号 2 关联的分支的末尾。您可以使用 g+g- 沿着此分支移动。此时g+ 什么都不做(你在叶子上)。如果你按g-,“old”将被删除(你正在遍历第一个撤消树)。也就是说,如果你用g-删除“old”并再次按g+,“old”将被重做。

        如果你输入

        :u 3
        

        您将跳转到第二个撤消分支的叶子,它将显示:

        this is a new line
        

        【讨论】:

          【解决方案8】:

          undotree 包是用纯 vimscript 编写的,所以没有要求。

          并在为时已晚之前将其添加到您的 vimrc 中:

            set nobackup
            set noswapfile
            set nowritebackup
            set undolevels=10000         " use many levels of undo
            set history=10000    " After nocompatible
          
            if has('persistent_undo')
              set undodir=$HOME/.vim/undo
              set undofile 
            endif 
          

          【讨论】:

            猜你喜欢
            • 2012-09-26
            • 2011-08-07
            • 2013-04-19
            • 2018-04-29
            • 1970-01-01
            • 2010-12-06
            • 2015-03-09
            • 2015-08-13
            • 1970-01-01
            相关资源
            最近更新 更多