Follow @learnvim for more Vim tips and tricks!
Vim's undo can do things that many text editors can't. It can travel across time, create branches in history, and preserve undo history. How cool is that?
In this article, you will learn about vim undo to boost productivity. What I'll cover:
- Basic undo/ redo
- Persistent undo
- Undo tree
- Time travel
Basic undo/redo
You can do basic undo with u
and redo with Ctrl-r
in normal mode.
For command-line alternatives, use:
:u[ndo]
:red[o]
Vim sets a maximum number of how many times you can undo in undolevels
option. You can check it with :echo &undolevels
(mine is set to be 1000 default). To change it to 2000, run :set undolevels=2000
.
Persistent undo
When you close a text editor, normally you lose all your undo history. This means when you open that file again, you can't immediately undo.
However, vim can preserve your undo history inside an undo file with :wundo[!] myUndoFile
.
Let's do a quick example. Create a file hello.txt
. Type:
Hello one
Go back to normal mode, type another line below:
Hello two
Go back to normal mode, type another line below:
Hello three
Go back to normal mode.
If you undo once, it will remove "Hello three" line. Undoing twice will remove "Hello two" and "Hello three", etc. Again, everything works as expected. Let's redo everything until you get all your texts back.
Hello one
Hello two
Hello three
Create your undo file:
:wundo! hello.undo
Then exit vim. By now you have hello.txt
and hello.undo
in your directory. When you open up hello.txt
again, you can't undo anything immediately. To restore our undo history, let's read from our undo file:
:rundo hello.undo
Your previous undo history is loaded. Now if you undo, vim will remove "Hello three". If you undo twice, vim will remove "Hello two" and "Hello three", etc. It's like you never closed vim!
Undo tree
Vim has an undo tree that grows every time you create an undo branch. I will explain what undo branch later.
Create another file hello2.txt
. Type:
Hello one
Go back to normal mode, type another line below:
Hello two
Go back to normal mode.
If you undo once, it undoes "Hello two", leaving you with only "Hello one". Everything is good so far. Redo everything until you're back with "Hello one" and "Hello two".
Undo once to remove "Hello two" so you have only "Hello one".
This time, type "Hello three" below "Hello one". You now have:
Hello one
Hello three
Now if you undo, vim removes "Hello three", leaving you with only "Hello one". If you undo again, vim removes "Hello one", leaving you with blank file! You just created a branch in your undo history. You can't get your "Hello two" text back once you create an undo branch... or can we?
Redo everything until you get these texts back.
Hello one
Hello three
Now type g-
. Voila! You get your old "Hello two" back.
Hello one
Hello two
Type g+
. You get "Hello three" back.
Hello one
Hello three
What happened? When we still had "Hello one" and "Hello two" and did an undo once (losing "Hello two"), we typed "Hello three". A new undo branch was created. Every time you undo and make changes, Vim create a new undo branch. Have you seen a time-travel movie when the protagonist went back to the past and altered the future? It is somewhat similar to this. We went back to the past state with undo, modified a file, and altered the undo history.
Vim can go to different undo branches (or I should say "alternate reality") with g-
and g+
.
In addition, you can also do :earlier n
or :later n
, where n
is the newer / later state number. To go back to 2 branches before, do :earlier 2
.
To see all undo branches' leafs, you can do:
:undol[ist]
You should see something like this (yours may look slightly different from mine).
number changes when saved
1 1 07:59:26
4 2 07:59:43
5 3 08:00:55
To repeat, every time you undo and make changes instead of redo, you create a new branch.
It is not intuitive at first. Play around with it.
Time travel
Vim can also travel to a state in the "past" and "future". The :earlier
and :later
commands accept time as an argument:
:earlier 5s " go to older state 5 seconds before
:earlier 5m " go to older state 5 minutes before
:earlier 5h " go to older state 5 hours before
:earlier 5d " go to older state 5 days before
You can use same argument on :later
:
:later 5s " go to newer state 5 seconds after
:later 5m " go to newer state 5 minutes after
:later 5h " go to newer state 5 hours after
:later 5d " go to newer state 5 days after
Finally, you can tell vim to go to older state "5 saves ago" with :earlier 5f
. and to later state "3 saves later" with :later 3f
.
Conclusion
Vim has a powerful undo system.
It can have virtually unlimited undos (as many as your machine's memory permits) by setting undolevels
.
It can create an undo file to preserve undo history with :wundo
and :rundo
.
Each time you undo and make different changes, you create a branch in your undo history. You can view these branches with :undol
and travel with g-
and g+
.
:earlier
and :later
can be used to jump to different states based on: time, file writes, and undo branches.
Undo tree is not an easy concept to grasp initially. I still struggle to wrap my head completely around it. Play around with it to get the basics. It can be a powerful assets in your coding.
Thanks for reading. Now go and create a time paradox >=).