2010-11-15

One of the advantages that text-editors have over daily life is the ease of
undoing things. Emacs in particular has a powerful undo-system to return to
the previous state of things.

Undo can be activated by pressing C-x u or C-_; if you are more comfortable
with using C-z for undo (as is the standard in many non-Emacs environments),
you can of course add that key binding as well, by putting in your .emacs:

(global-set-key (kbd "C-z") 'undo)

This overrides the default of C-z triggering suspend-frame, which is not a
great loss for most people.

Emacs-undo has some nice features - for example, if you have selected some text
('marked a region'), the undo operation only applies to that area. At the same
time, however, the undo-model can be confusing: in emacs, undo is treated like
any other command, which means that undo can be applied even to… undo,
which is different from what most other editors do. Let me give an example – if
it's confusing or tedious then, well, that's what it is…

Suppose I type

hello
world

now I press C-_, and I get

hello

Now I type foo

hello
foo

And press C-_C-_; and I get back:

hello
world

This is because we're 'undoing the undo' of adding the word 'world', and thus,
it reappears! When you try this in most other editors, it would result in

hello

because those editors completely forget about 'world' after it is undone.

So, emacs' model is strictly more powerful - but some (many? )people find it a
bit confusing, esp. when a series of 'undos' is interrupted by a 'do'.

If you prefer the model that many other editors use, you might be interested in
redo-mode, in particular in RedoPlus. Using that package, undo (or rather,
redo) follows a different model. In that model, redo is 'special': it's
not registered as a buffer change, and as such it's conceptually different
from the redo=undo-undo model that emacs uses by default. As seen above, you
actually lose some information in the process.

Yet another way to tackle the undo-problem is implemented by UndoTree: the
states of your buffer are seen as nodes in a tree, and you can freely move to
specific nodes. UndoTree is as powerful as the emacs system, yet easier to
understand. It can even visualize the tree of changes - and you can then by
clicking on a node go back to the corresponding buffer state.

Now, when using UndoTree, let's look at our example again:

We started with:

hello
world

then did C-_ (which removed 'world') and typed 'foo' to get:

hello
foo

Now press C-u again, and 'foo' disappear. Now we press C-x u
(undo-tree-visualize) and we get a buffer with:

|
o
|
|
x
|
/ \
o o

and we can now visually move to any of the nodes, and our buffer is instantly
brought back. Cool! The two branches correspond to the states 'world' and 'foo'.
I have been undo-tree-mode for the last few weeks, and it works very well:
usually I don't even notice it, but when I need the extra power, it's there.

I am told that UndoTree is inspired by the way the vim-text editor does
this. Anyway, there is another very powerful feature in the vim undo-system
that would be nice to have in emacs to: time-based undo. In vim you can e.g. say
something like:

:earlier 5m

to go to the state of your buffer 5 minutes ago. That would be a nice addition
for undo-tree-mode!

UpdateTavis Rudd notes that pressing t in undo-tree-visualizer-mode
(i.e.. what you see when your press C-x u) will give you timestamps instead of
o and x:

“Many years”, eh? That's a depressing but all too common story with Emacs users, and one reason why one should try to make good use of Emacs' self-documenting nature - even for the seemingly simple things...

'C-h F undo RET' will show you that in fact 'C-/' is the primary binding for the 'undo' command. The others are aliases - 'C-x u' “for beginners”; 'C-_' “for some text-only terminals”.

As usual, thank you for shedding some light into another dark corner in emacs.I wanted to undo without using 3 keys (or two mouse clicks for menu, undo). even C-_ is three keys counting the shift key.C-/ is two, and easy to repeat when you want to undelete several deletions, like a whole word or line after using the del key.Thanks!