Not really a blog, just some stuff that a future me might need to remember one day.
I know u
to undo and Ctrl-r
to redo but what happens when my undo
tree branches?
Suppose you start with an empty file and start entering names one at a time:
bob
alice
jim
Then you decide you want to backtrack, so you hit u
twice to remove
jim
and alice
leaving just:
bob
At this point it’s easy to get back to all the previous states using
either u
to go back or Ctrl-r
to go forward.
But then you carry on editing adding a few other names:
bob
dorothy
derek
So now what happens if you want to go back to the state of the file
before the first undo? Well you would be out of luck if you are just
relying on u
and Ctrl-r
because the undo tree has branched.
So it looks like Vim has ‘lost’ some of our intermediate editing steps. But that isn’t really the case, the undo tree still every step we took, we just need the commands to navigate that tree.
###g-
and g+
There are a couple of different ways to solve this problem. Perhaps the
simplest method is to use the g-
and g+
commands. These simply step
back and forward through your changes in time order. So from any given
point you can always get back to another change by repeatedly using g+
(eventually) regardless of whether it is in the current undo tree branch
or not.
Using these commands can be a bit confusing - partly because it’s far more natural to navigate a single branch of the tree. But also because these commands appear to merge normal text changes with undo/redo operations into a single ‘change’.
###:undolist
If you want to discover other (lost) branches in the undo tree you can
use the :undolist
command. This doesn’t list every change, only leaf
nodes of the undo tree. Here is an example from the undo tree I
generated writing this post:
number changes when saved
45 44 18:34:38 6
55 54 56 seconds ago
Here change number 45 represents a separate branch of the tree to the one I am currently on. Change number 55 is where I am now.
If I want to skip to the other branch I can use the undo command giving it a change number:
:undo 45
From here I could use u
and Ctrl-r
to move back and forth on that
branch.
###:earlier
and :later
These commands work much the same as g+
and g-
when issued without
an argument. However you can pass a time interval, suppose you want to
go back 10 minutes:
:earlier 10m
This can be handy if you have a good idea of when you were in the desired state, personally I find it hard to guess times like this.