undo






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





No comments:

Post a Comment

Followers

Popular Posts