Emacs:清理撤销树

12

我注意到在较长的编辑会话中,调用undo-tree(C-x C-u)变得越来越慢。我认为原因是随着树的增大,解析它需要更长时间(因为它跟踪了自打开文件以来所有我的编辑)

有没有办法清除打开文件的撤销树?我尝试了C-x C-vfind-alternate-file),但这会重新打开文件并重置光标(在org-mode等模式下折叠列表)

4个回答

11

使用M-: (setq buffer-undo-tree nil)命令重置buffer-undo-tree变量。这将丢弃缓冲区的整个撤消历史记录,如undo-tree.el所记录的。

也可以使用类似以下代码将其制成命令并绑定到键:

(defun clear-undo-tree ()
  (interactive)
  (setq buffer-undo-tree nil))
(global-set-key [(control c) u] 'clear-undo-tree)

谢谢。你知道你的回答和@npostavs的回答有什么区别吗? - Amelio Vazquez-Reina
1
一个区别是undo-tree-discard-history尝试根据变量undo-limitundo-strong-limitundo-outer-limit修剪历史记录,而我的解决方案则删除整个撤消历史记录。更重要的是,undo-tree-discard-history在每次撤消/重做/切换分支操作时自动调用,所以显然它对您不起作用。 - user4815162342

4
请注意,此提示可能已过时。从版本0.6开始,默认情况下,undo-tree使用“lazy tree-drawing”。这显著加快了大型撤消树的可视化,只绘制可见部分(并在您移动树时根据需要扩展它)。有关更多详细信息,请参见undo-tree-visualizer-lazy-drawing变量的文档字符串。
如果您仍然想丢弃整个撤消树,则手动将buffer-undo-tree设置为nil是一个好的一次性解决方案。较长期的解决方案是将undo-limitundo-strong-limitundo-outer-limit的值减小,以限制撤消树的大小,即在丢弃旧数据之前限制其存储的撤消历史记录量。
手动调用undo-tree-discard-history没有意义。每当您执行与撤消相关的任何操作时,它都会自动调用。

3

有时我需要清空一个缓冲区的撤销树,因为我复制了一些包含当前编码无法显示的字符的文本。所以我发现@Amelio Vazquez-Reina的函数非常有用。不过,我不想让这个函数被意外调用,所以我添加了一个确认提示和一个检查,确保buffer-undo-tree确实是一个缓冲区本地变量:

(defun clean-undo-tree ()
"Clear current buffer's undo-tree.
Undo-tree can cause problems with file encoding when characters
are inserted that cannot be represented using the files current
encoding. This is even the case when characters are only
temporarily inserted, e.g. pasted from another source and then
instantly deleted. In these situations it can be necessary to
clear the buffers undo-tree before saving the file."
  (interactive)
  (let ((buff (current-buffer)))
    (if (local-variable-p 'buffer-undo-tree)
        (if (y-or-n-p "Clear buffer-undo-tree? ")
            (progn
              (setq buffer-undo-tree nil)
              (message "Cleared undo-tree of buffer: %s" (buffer-name buff)))
          (message "Cancelled clearing undo-tree of buffer: %s" (buffer-name buff)))
      (error "Buffer %s has no local binding of `buffer-undo-tree'" (buffer-name buff)))))

1

您可以修剪树而不是丢弃整个树:

undo-tree-discard-history is a compiled Lisp function in
`undo-tree.el'.

(undo-tree-discard-history)

Discard undo history until we're within memory usage limits
set by `undo-limit', `undo-strong-limit' and `undo-outer-limit'.

调用函数(undo-tree-discard-history)和将变量(buffer-undo-tree)设置为nil有什么区别?(如@user4815162342的答案中所述) - Amelio Vazquez-Reina
1
@user273158:根据user4815162342的评论,使用reduce而不是完全删除。我没有注意到它被称为每个撤消/重做。可以降低限制以使其更有效。 - npostavs

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