有没有办法让Emacs在会话之间保存撤消历史记录?

有没有办法让Emacs在会话之间保存撤消历史记录?,emacs,Emacs,有没有办法让EMACS在会话之间保存撤消历史记录 我知道savehist库、saveplace库、desktop库和windows库,它们都提供了一些会话控制,但似乎都没有保存撤销历史记录。以下是我编写的一些代码,似乎可以实现这一点。它不是防弹的,因为它不能处理Emacs所处理的所有复杂的文件处理(例如,覆盖自动保存文件的放置位置、符号链接处理等)。但是,对于我操纵的一些简单文本文件,它似乎起到了作用 (defun save-undo-filename (orig-name) "given

有没有办法让EMACS在会话之间保存撤消历史记录


我知道savehist库、saveplace库、desktop库和windows库,它们都提供了一些会话控制,但似乎都没有保存撤销历史记录。

以下是我编写的一些代码,似乎可以实现这一点。它不是防弹的,因为它不能处理Emacs所处理的所有复杂的文件处理(例如,覆盖自动保存文件的放置位置、符号链接处理等)。但是,对于我操纵的一些简单文本文件,它似乎起到了作用

(defun save-undo-filename (orig-name)
  "given a filename return the file name in which to save the undo list"
  (concat (file-name-directory orig-name)
          "."
          (file-name-nondirectory orig-name)
          ".undo"))

(defun save-undo-list ()
  "Save the undo list to a file"
  (save-excursion
    (ignore-errors
      (let ((undo-to-save `(setq buffer-undo-list ',buffer-undo-list))
            (undo-file-name (save-undo-filename (buffer-file-name))))
        (find-file undo-file-name)
        (erase-buffer)
        (let (print-level
              print-length)
          (print undo-to-save (current-buffer)))
        (let ((write-file-hooks (remove 'save-undo-list write-file-hooks)))
          (save-buffer))
        (kill-buffer))))
  nil)

(defvar handling-undo-saving nil)

(defun load-undo-list ()
  "load the undo list if appropriate"
  (ignore-errors
    (when (and
           (not handling-undo-saving)
           (null buffer-undo-list)
           (file-exists-p (save-undo-filename (buffer-file-name))))
      (let* ((handling-undo-saving t)
             (undo-buffer-to-eval (find-file-noselect (save-undo-filename (buffer-file-name)))))
        (eval (read undo-buffer-to-eval))))))

(add-hook 'write-file-hooks 'save-undo-list)
(add-hook 'find-file-hook 'load-undo-list)

默认情况下,桌面保存模式不保存缓冲区撤消列表。你只要告诉他就行了

(add-to-list 'desktop-locals-to-save 'buffer-undo-list)
似乎支持这一点:

(add-to-list 'session-locals-include 'buffer-undo-list)

从版本0.4开始,撤消树支持在“开箱即用”会话之间持久存储撤消树数据。(请注意,在较新的版本中,有与此功能相关的重要错误修复;撰写本文时的最新版本是0.6.3。)

只需启用
undo tree auto save history
customization选项,即可在undo tree缓冲区中自动保存和加载undo history。或者使用
撤消树保存/加载历史记录
命令手动保存和加载撤消历史记录


您至少需要Emacs版本24.3才能可靠地工作,但使用最新版本的Emacs,它工作得非常好。

将以下内容添加到.Emacs文件中:

(global-undo-tree-mode)
(setq undo-tree-auto-save-history t)
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
解释
  • (全局撤消树模式)
    启用撤消树

  • (setq undo tree auto save history t)
    启用撤销历史的自动保存

  • (setq undo tree history directory alist'((“.”~/.emacs.d/undo”))
    ,这样您的项目就不会被undo history保存文件弄得乱七八糟


我已使用此处提供的信息成功地恢复了撤消历史记录:

我没有修补原始文件
desktop.el.gz
,而是创建了一个临时覆盖
(缓冲区局部变量)
的通知,然后将其与收集缓冲区信息的函数一起使用

(defun +append-buffer-undo-list-to-buffer-local-variables-advice (orig-fn &rest args)
  "Override `buffer-local-variables' and call ORIG-FN with ARGS.
There is a bug in Emacs where the `buffer-undo-list' data is
missing from the output of `buffer-local-variables'. This
advice temporarily overrides the function and appends the
missing data."
  (let ((orig-buffer-local-variables-fn (symbol-function 'buffer-local-variables)))
    (cl-letf (((symbol-function 'buffer-local-variables)
               #'(lambda () (append (funcall orig-buffer-local-variables-fn)
                               `(,(cons 'buffer-undo-list buffer-undo-list))))))
      (apply orig-fn args))))

(advice-add #'desktop-buffer-info :around #'+append-buffer-undo-list-to-buffer-local-variables-advice)
(push 'buffer-undo-list desktop-locals-to-save)
(desktop-save-mode 1)

我希望这对其他人有帮助。

好家伙,这看起来很棒,我使用了undo tree,所以它对我来说不是开箱即用的,但我打赌我可以让它与undo一起工作-tree@openist看起来您可以简单地检查
缓冲区撤消树
,并以与代码保存
缓冲区撤消列表
相同的方式保存该树,这也是我的假设,不幸的是,尽管我仍然无法让它在禁用撤消树模式的情况下工作。我仍然在调试它,我对ELISP还很陌生,但是当我加载一个文件时,撤消历史记录不可用。正在调用钩子,但我不确定它在哪里崩溃。@openist是否为撤消树修复了此问题?能否将
.undo
文件保存在
~/.emacs.d
文件夹下@TreyJacksonExcept似乎没有办法让它将撤销历史记录保存在与您正在编辑的文件相同的目录之外的其他地方。只需覆盖.emacs中的
undo tree make history save file name'函数,以完全相同的方式覆盖
make auto save file name'。对于自动保存,我只需覆盖自动保存列表文件前缀和auto-save-file-name-transforms。覆盖
undo tree make history save file name
调用
make auto save file name
,然后附加一个特定于undo tree的后缀。然后它将只使用与您的自动保存相同的目录。在最新版本的undo tree中,您还可以自定义
undo tree history目录列表”(参见
backup directory列表)。上述答案(本身)在使用当前版本的Emacs Trunk时,由于函数
(缓冲区局部变量)中排除了
缓冲区撤消列表
,因此该值不足
——以下线程的链接讨论了一种变通方法,即将
缓冲区撤消列表推送到
ll
函数的末尾
桌面缓冲区信息
——它刚好在最后一个
dolist
部分之后,最后一个
ll
被抛出之前。--i、 例如,
(push(cons'buffer undo list buffer undo list)ll)
这个变量是什么
ll
?该推送到哪个列表?似乎这仍然不起作用,我真的希望能够保存缓冲区撤消列表。谢谢,没关系,我在
desktop.el.gz
文件中找到了它,它在
桌面缓冲区信息
函数中。我正在
分配自由变量“undo tree auto save history”
,这会有问题吗?