Reputation: 219
I was trying to make persistent undo history work in emacs.
I have (setq undo-tree-auto-save history t)
. The history is indeed saved when I save file. But when I open file, the undo history is not loaded until I use undo.
So if I open a file and make some changes, then run M-x undo-tree-visualize
, the previous undo tree is gone, only the recent changes are there. But if I run M-x undo-tree-visualize
first, then I can see the old undo tree. Or if I just use undo before making any changes, the old undo history is loaded and the undo works as expected.
Edit: My configuration looks like this: https://gitlab.com/snippets/22693
Edit2: This problem still happens with the most minimal configure file:
;;; init.el --- user init file -*- no-byte-compile: t -*-
(load-file "~/.emacs.d/undo-tree.el")
(global-undo-tree-mode 1)
(setq undo-tree-auto-save-history t)
Upvotes: 2
Views: 1738
Reputation: 3
Put the (global-undo-tree-mode)
in the :init
will auto load history if you're using use-package
Example:
(use-package undo-tree
:init
(global-undo-tree-mode)
:custom
(undo-tree-auto-save-history t)
(undo-tree-history-directory-alist '(("." . "~/.config/emacs/undo-tree-history")))
(undo-tree-visualizer-diff t)
(undo-tree-visualizer-timestamps t))
Upvotes: 0
Reputation: 1
Reason for this behavior is that when you start up emacs and open up file in buffer even with undo-tree-auto-save-history
enabled so that undo-tree-load-history
is called as it should be, buffer-undo-list
is initially set to nil
. If you make an edit before invoking any functionality of undo-tree, buffer-undo-list
will have value that doesn't end with an undo-tree-canary
.
When undo-list-transfer-to-tree
sees buffer-undo-list
not ending with undo-tree-canary
, it will discard current buffer-undo-tree
and construct new one with the value of buffer-undo-list
which only have undo history of your initial edit. Consequently, buffer-undo-tree
previously built by undo-tree-load-history
is deleted, and you are left with fresh, minimal buffer-undo-tree
only with single undo history.
So what I did to prevent this from happening was to initialize buffer-undo-list
with undo-tree-canary
by advising undo-tree-load-history-hook
which should call undo-tree-load-history
with undo-tree-auto-save-history
set to t
, and it is also called for opening file as part of find-file-hook
.
That is, I added this line of code to my init file:
(advice-add 'undo-tree-load-history-hook :after (lambda () (setq buffer-undo-list '(nil undo-tree-canary))))
Upvotes: 0
Reputation: 17
I just want to chime in that I experience a similar thing.
if I emacs file-x
from the terminal, earlier undo tree history for file-x
is not is not available to me before I undo-tree-load-history
. However, when I open emacs and then :edit file-x
, the history is loaded just fine.
I'm using spacemacs 0.105.19
, with emacs-24.5.1
.
My .spacemacs
is https://pastebin.com/VNWtB0F1
Upvotes: 0
Reputation: 5
Have you tinkered with the order you are loading your plugins as well as files you open automatically via init.el or .emacs? That did the trick for me. Evil requires Undo-Tree. So everything having to do with undo-tree should fire before you load Evil. Especially if you use ":e" instead of "find-file" for loading files. A least on my system that solved this issue.
Upvotes: 0
Reputation: 453
When undo-tree-auto-save-history
is enabled, undo history is loaded from file by the undo-tree-load-history-hook
function, which gets added to find-file-hook
. So undo history will be loaded automatically when you open a file with undo-tree-mode
enabled.
@djangoliv is right: this will only work if global-undo-tree-mode
is enabled, because undo-tree-mode
needs to be enabled before find-file-hook
is called. Perhaps the undo-tree-mode
minor-mode function ought to attempt to load history if it detects the buffer hasn't been modified since the last undo history save. But at the moment, it doesn't.
However, your config does enable global-undo-tree-mode
, so this can't be the issue.
History loading works just fine for me with global-undo-tree-mode
enabled. So unless you give a complete MWE that reproduces your problem -- i.e. step-by-step instructions starting from "emacs -Q" and including Emacs and undo-tree version numbers -- you're unlikely to get much more help here. (Also, note that stackexchange is not a bug tracker. Bug reports should be sent by email to the address listed at the top of the package.)
Upvotes: 1
Reputation: 219
How come no one has ever noticed this? There's a bug in undo-tree.
The function undo-list-transfer-to-tree failed to append 'undo-tree-canary to buffer-undo-list, which cause it to discard the content of buffer-undo-tree.
I'm still looking into it to see if I can find a solution. Simply append 'undo-tree-canary to buffer-undo-list causing it to discard to content in buffer-undo-list instead
Edit: The solution is indeed to put canary at the end of buffer-undo-list
(when (not (eq (last buffer-undo-list) 'undo-tree-canary))
(setq buffer-undo-list (append buffer-undo-list '(nil undo-tree-canary))))
Upvotes: 1