Fun With Undo-Tree-Mode

No more. This ends now. This will not stand!

What’s my problem, you ask? I’ll tell you what. Emacs’ stupid undo system is my problem. Humor me for a second; fire up Emacs, and type the following:

foo bar baz

Still with me? Good, now press

C-x u

…baz disappeared. “Well, duh! If you’re gonna whine about the fact that C-u doesn’t undo, then maybe you shouldn’t be using Emacs…” you say. Were that my issue, I’d be inclined to agree. Unfortunately, the problem is much worse. Enter the following into your buffer:

oof

…then…

C-x u C-x u

See that? Yeah… Not OK. The buffer should be:

foo

with the entry of oof and bar having been undone. Instead, the buffer is:

foo bar baz

with the entry of oof and the undoing of the undoing of the entry of baz having been undone.

Apparently, an undo operation itself goes onto the undo stack in Emacs. Meaning that if you undo enough times, it will redo all the undone operations, then undo them again, then undo the operations before. This lets us get the buffer back into any state it has ever been in, which sounds nice on paper. In practice, it’s yet another way that Emacs goes its own way, the rest of the world be darned. And I gotta say, its pretty annoying. In a normal program, you can just hold Ctrl+u, and watch the undoes fly. In Emacs, you get to press C-x, release, press u, and release to undo one thing. Then do it again n times.

Luckily for us, this being Emacs, there is likely a better way out there.

undo-tree-mode

Undo tree mode is a minor mode for Emacs that helps us deal with this undo behavior. In the short amount of time that I’ve played with it, I’d say it makes the on-paper benefit of Emacs’ undo behavior a reality. But first, some installation.

Undo-tree-mode is in Melpa stable, however, I was unable to get it to work. To install undo-tree-mode, you can install it via Melpa, then add the following to your .emacs file:

(global-undo-tree-mode)

Unfortunately, when I restarted Emacs, I got the following error:

Symbol's function definition is void: global-undo-tree-mode

Adding:

(require 'undo-tree)

does nothing to alleviate this situation, neither does opening undo-tree.el and entering:

M-x byte-compile-file

However, I was able to install it manually. First, I deleted all the files for undo-tree-mode from my .emacs.d/ directory. Then I downloaded the current version of the plugin from the author's website, and placed it in my ~/.emacs.d/, naming it undo-tree.el. Finally, I added the following lines to my .emacs file:

(add-to-list 'load-path "~/.emacs.d/") (require 'undo-tree) (global-undo-tree-mode t)

That first line is only required if you haven’t already added it elsewhere. Restart Emacs, and you should see that the Undo-Tree minor mode is active.

Climbing The Tree

Now, let’s try that previous sequence of events.

foo bar baz C-x u

A new window should appear with the following in it:

s | | o | | o | | o | | o | | x

Neat. This represents the operations that you did. Try clicking through them (you can also use the arrow keys to browse). Each node is a state of the document, x is the current state, and s is the initial state. Select the node two nodes up from the leaf to undo entry of baz. Lets continue our sequence:

oof C-x u

You should see a new tree that looks something like this:

s | | o | | o | | o | | o | / \ x o | | o

If you click around the tree, you’ll see the various states of your buffer. You’ll see that it is simple to restore any previous state of the buffer.

Now this is something I can get used to!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: