12

Every so often I run into bugs in undo-tree, where I can't redo, with the following:

primitive-undo: Unrecognized entry in undo list undo-tree-canary

Links to references to this issue:

This is really bad and can cause loss of work if you didn't happen to save the newest version of the file.


Since I never use the branching undo tree functionality, is it possible to use emacs linear undo with evil mode?


Note: I've tried setting (global-undo-tree-mode -1) directly after (evil-mode 1) which disables undo tree, but redo (Ctrl-R) doesnt work after doing this.

ideasman42
  • 8,375
  • 1
  • 28
  • 105
  • 2
    Emacs has no 'redo' command (you instead interrupt the undo sequence, and then undo the preceding sequence of undo commands). It sounds like what you've done has worked correctly. – phils Mar 13 '17 at 10:55
  • 2
    If your goal is to get undo-tree fixed, please get in contact with its author and write them an email. Complaining on emacs-devel won't fix things. Likewise, if your goal is to allow Evil to use vanilla undo, open a ticket on its bug tracker. Keep in mind though that vanilla undo is undo only, there is no redo at all, only undoing the undo, hence why undo-tree is used in the first place. – wasamasa Mar 13 '17 at 13:18
  • 1
    My goal is to have working undo/redo. I'm not that fussed exactly how. Since I don't use the *tree* functionality of undo-tree I thought it might be simplest to use emacs built-in undo. Even so, I've reported to the bug to the undo-tree author. – ideasman42 Mar 14 '17 at 04:50
  • 1
    I have the exact same issue, it happens about once daily and is very frustrating – cjohansson Sep 12 '17 at 08:32
  • Update: emacs-28 now has `undo-redo` built-in. – ideasman42 Apr 12 '22 at 22:50

4 Answers4

8

The author of undo-tree.el, Toby Cubitt, is presently too busy to fix this particular bug. If he has time in the future, he may look into the issue further. The author has indicated that he has difficulty reproducing the error reliably, and was recently unable to reproduce it using the master branch. It only occurs when using undo/redo-in-region. The author suggests just turning off the undo/redo-in-region feature in the meantime.

I would strongly encourage anyone who is motivated to come up with a reliable way to reproduce the issue starting from emacs -q using both the current stable release of Emacs (e.g., 25.2.1) and also with the most recent version of the master branch, and then submit those recipies to bug tracking number 16377 with carbon copies to the participants (Stefan, Toby, Barry, and Keith).

The main tracking number is 16377, and there is a related tracking number 16523:

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=16377

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=16523

Here is the workaround that turns off the undo/redo-in-region feature:

(setq undo-tree-enable-undo-in-region nil)
lawlist
  • 18,826
  • 5
  • 37
  • 118
  • 1
    This workaround doesn't work - I tried it and still get broken redo sometimes. – ideasman42 Dec 04 '17 at 01:53
  • 1
    @ideasman42 -- As far as I know, Toby Cubitt is presently unaware that the error can occur when `undo-tree-enable-undo-in-region` is `nil`; and, I have also never seen it occur outside of using undo-in-region. If you are able to come up with a recipe to reproduce the error, please report it to the Emacs team -- a carbon copy to Dr. Cubitt would also be helpful, and if it is not too much trouble, I sure would appreciate the recipe if you are able to come up with one that is reliable. Sorry that you are having issues ... – lawlist Dec 04 '17 at 03:21
  • I did mail a bug report with no response (some months back). Projects like this that many people depend on should really have a public bug tracker. – ideasman42 Dec 04 '17 at 04:30
  • 1
    16377 and 16523 are indeed public Emacs bug tracking numbers and `undo-tree` is officially a part of the `elpa` repositories. You can use the standard report Emacs bug; however, the end result may be the same -- i.e., waiting for Dr. Cubitt to find some free time in his busy schedule ... At some point, another undo guru may come along and assist in maintaining the package. I spent a great deal of time creating a custom fork of undo-tree that can undo/redo in a semi-linear fashion, and I still have only a basic understanding of how it all works ... – lawlist Dec 04 '17 at 05:09
4

Since answering this question, evil now supports pluggable undo systems.

So if you want to use undo-fu instead of undo-tree you can do this as follows.

(use-package evil
  :init
   (setq evil-undo-system 'undo-fu))

(use-package undo-fu)

Valid options for evil-undo-system include:

  • undo-fu the undo-fu package.
  • undo-tree the undo-tree package.
  • undo-redo for emacs-28's undo/redo support.
ideasman42
  • 8,375
  • 1
  • 28
  • 105
  • You may want to mention the variable to customize for people not into use-package and maybe mention other undo systems. – wasamasa Jan 12 '21 at 09:25
1

Apparently you can edit evil-pkg.el in ~/.emacs.d/elpa/evil-xxxxxxx/ dir and delete undo-tree as a requirement :

(define-package "evil" "20140109.605" "Extensible Vi layer for Emacs." '((goto-chg "1.6")))

source

DaftWooly
  • 111
  • 1
  • That will break undo/redo which is not what OP wants. – wasamasa Jul 16 '17 at 17:24
  • 1
    The author of the blog I linked said it allowed him to use emacs' vanilla undo, that seems to be what OP wanted when he said "disable undo tree". – DaftWooly Jul 16 '17 at 17:48
  • 1
    This should really be a last-resort thing, because the next time you update packages, this customization will be overwritten. It would be better to find a way to get the behavior you want by configuring your init file. – zck Jul 17 '17 at 00:29
  • I agree, unfortunately it seems to be the only way to disable undo-tree in evil. – DaftWooly Jul 17 '17 at 09:09
  • Doesn't work for me. I commented out the requirement, and moved `undo-tree` package out of the way so it wouldn't load. Now using "redo" fails with `Wrong type argument: commandp, redo`. – Hi-Angel Feb 12 '19 at 23:27
  • @Hi-Angel I had the same error, and it was caused by my defining a minor-mode keymap that used "C-/" in one of the bindings . There are other things that can cause it; see https://www.reddit.com/r/emacs/comments/94r6o3/cant_redo_anymore/ and https://github.com/ProofGeneral/PG/issues/430. – Patrick Brinich-Langlois Mar 27 '20 at 23:06
1

Edit, this is now a package which can be used for undo/redo with evil-mode - undo-fu.


Adding answer to own question since I've been using evil w/o undo-tree for some time now.

This works surprisingly well to undo/redo which wraps emacs undo without anything heavy like undo-tree or redo+.

(global-undo-tree-mode -1)

(defun simple-redo ()
  (interactive)
  (let
    (
      (last-command
        (cond
          ;; Break undo chain, avoid having to press Ctrl-G.
          ((string= last-command 'simple-undo) 'ignore)
          ;; Emacs undo uses this to detect successive undo calls.
          ((string= last-command 'simple-redo) 'undo)
          (t last-command))))
    (condition-case err
      (progn
        (undo) t)
      (user-error
        (message "%s" (error-message-string err)))))
  (setq this-command 'simple-redo))

(defun simple-undo ()
  (interactive)
  (let
    (
      (last-command
        (cond
          ;; Emacs undo uses this to detect successive undo calls.
          ((string= last-command 'simple-undo) 'undo)
          ((string= last-command 'simple-redo) 'undo)
          (t last-command))))
    (condition-case err
      (progn
        (undo-only) t)
      (user-error
        (message "%s" (error-message-string err)))))
  (setq this-command 'simple-undo))
ideasman42
  • 8,375
  • 1
  • 28
  • 105