Undoing and redoing

Author

Marie-Hélène Burle

Undoing and redoing are operations so common while editing files that we don’t think about them much. Most software however have a poor undo/redo system in which edits get lost all the time.

Emacs’ undos never loses edits and undo-tree brings a wonderful undo/redo system to it.

Undo systems

Linear systems: classic undo/redo

You have some file:

You make some edit:

You make another edit:

And another one:

You can undo:

You can undo some more:

You can also redo:

Now, you make some new edit. From this point on, some edits are lost:

You can still undo:

And you can redo your last undo, but you can’t access all previous states of the file:

Linear systems: Emacs

You have some file:

1

You make some edit:

1

2

You make another edit:

1

2

3

And another one:

1

2

3

4

The first undo adds a new point to the chain of edits, reversing the effects of the last edit:

1

2

3

4

3

More undoing keeps adding points to the chain:

1

2

3

4

3

2

There is no proper redo. Instead, you stop undoing, then start again to undo the undo:

1

2

3

4

3

2

3

You can make new edits

1

2

3

4

3

2

3

5

Nothing ever gets lost, but you might get headaches. For instance, to go back to the beginning, you have to do:

1

2

3

4

3

2

3

5

3

2

3

4

3

2

1

Non linear system: undo-tree

You have some file:

You make some edit:

You make another edit:

And another one:

You can undo:

You can undo some more:

You can also redo:

Now, you make some new edit:

You can still undo:

You can switch branch and redo the old version:

Nothing ever gets lost and it is a lot more sane to navigate the history.
To to back to the beginning, you only have to do:

Compare this with the insane Emacs default system:

1

2

3

4

3

2

3

5

3

2

3

4

3

2

1

And this is an exceedingly simple example only involving 5 different file states. I let you imagine how it quickly explodes in complexity in real life situations 🙂

Now, the default Emacs system has the huge benefit to never lose any edit. It is already a huge improvement over the default system on most software! The thing is that when we undo and redo changes, linear systems are not ideal. A tree structure that can be fully navigated is just a more sensible solution.

Undo-tree was initially developed for Vim, so Vim can also use an ideal undo/redo system.

Installing and customizing undo-tree

This is a personal affair.

The minimal configuration when using straight (to download the package) and use-package to load it and customize it, looks like this:

(use-package undo-tree
  :straight t)

My personal configuration looks like this:

(use-package undo-tree
    :straight t
    :init
    (global-undo-tree-mode 1)
    :bind (("C-l" . undo-tree-undo)
           ("C-r" . undo-tree-redo)
           ("s-t" . undo-tree-visualize)
           :map undo-tree-visualizer-mode-map
           ;; go to selected undo state
           ("<return>" . undo-tree-visualizer-quit)
           ;; cancel (return to state before calling undo-tree-visualize)
           ("q" . undo-tree-visualizer-abort)))