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
!
Update Tavis 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
:
| | 18:54:20 | | 18:54:20 ________|___ / \ 18:54:15 18:53:37 | | | | 18:54:15 18:53:37 ___|___ | / \ | 18:54:10 18:53:43 18:53:36
8 comments:
After many years of emacs usage, I was pointed at the ever so great 'C-/' shortcut to undo. It took a day to readjust my muscle memory from 'C-_' to the new 'C-/' ... but there is no going back now.
Regarding time based undo, type 't' in the undo-tree-visualizer-mode buffer and it'll show timestamps rather than o's and x's.
Thanks, just installed UndoTree and it really rocks. Now both my editor and version control support branching. I feel enlightened.
@bruno
“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”.
Also, undo in a region will undo only changes done to that region (!!). So very useful!
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!
Undo-tree is a really great piece of code, customizable, ergonomic, really great. The only problem I have with it is undo-in-region, that works quite erratically ; I recommend disabvling it
Post a Comment