How do I do redo (i.e. "undo undo") in Vim?

Learn how do i do redo (i.e. "undo undo") in vim? with practical examples, diagrams, and best practices. Covers vim, undo, redo development techniques with visual explanations.

Mastering Undo and Redo in Vim: The 'Undo Undo' Explained

Hero image for How do I do redo (i.e. "undo undo") in Vim?

Learn how to effectively navigate your edit history in Vim, including the crucial difference between 'redo' and 'undo undo' to recover lost changes.

Vim's powerful editing capabilities extend far beyond simple text manipulation, offering a sophisticated undo history that can sometimes be confusing. While u (undo) is straightforward, understanding how to 'redo' or, more precisely, 'undo an undo' is key to efficient editing and recovering changes you thought were lost. This article will demystify Vim's undo tree and show you how to master your editing history.

The Basics: Undo (u) and Redo (Ctrl-r)

At its core, Vim provides two primary commands for navigating your edit history: u for undo and Ctrl-r for redo. When you make changes to a file, Vim records these changes as a sequence of operations. Each u command moves you backward through this sequence, reverting the last change. Conversely, Ctrl-r moves you forward, reapplying the changes that were undone.

iHello World
<Esc>
x
u
<C-r>

Basic undo and redo sequence in Vim.

In the example above, we insert 'Hello World', delete a character, then undo the deletion, and finally redo the deletion. This linear progression is simple enough, but Vim's undo history is not always a simple line; it's a tree.

Understanding Vim's Undo Tree

Unlike many other editors that maintain a linear undo history, Vim implements an 'undo tree'. This means that if you make some changes, then undo them, and then make new changes, Vim doesn't discard the undone branch. Instead, it creates a new branch in the undo tree. This is where the concept of 'undo undo' becomes critical.

flowchart TD
    A[Initial State] --> B{Edit 1}
    B --> C{Edit 2}
    C --> D{Edit 3}
    D -- u --> C
    C -- u --> B
    B -- New Edit --> E{Edit 4 (New Branch)}
    E -- <C-r> --> E
    E -- u --> B
    B -- <C-r> --> C
    C -- <C-r> --> D

Vim's undo tree illustrating branching history.

Consider the diagram: if you are at 'Edit 3', then press u twice to go back to 'Edit 1', and then make a 'New Edit', you've created a new branch. If you then press u again, you'll go back to 'Initial State'. If you want to get back to 'Edit 2' or 'Edit 3' from 'Initial State' (after making 'New Edit' and undoing it), Ctrl-r will only take you back to 'New Edit', not the original 'Edit 2' or 'Edit 3' branch.

The 'Undo Undo' Mechanism: Navigating Branches

To truly 'undo an undo' and explore different branches of your edit history, Vim provides a more advanced mechanism: the undo history commands. These allow you to jump to specific points in your undo tree, effectively letting you recover changes from older branches.

:earlier 1m
:later 30s
:undolist
:undo 5

Commands for navigating Vim's undo history.

Here's what these commands do:

  • :earlier {N} {time}: Jumps to a state N changes or time ago. For example, :earlier 10f goes back 10 changes, and :earlier 5m goes back to the state of the file 5 minutes ago.
  • :later {N} {time}: Jumps forward in time or changes. This is the true 'undo undo' for navigating branches.
  • :undolist: Shows a list of all saved undo points, including their change number and time. This is incredibly useful for understanding your undo tree.
  • :undo {N}: Jumps directly to undo point number N from the :undolist output.
set undofile
set undodir=~/.vim/undodir

Enabling persistent undo in your .vimrc.

1. Make some initial edits

Open a file in Vim and type iThis is the first version.<Esc>. Then, type oThis is the second version.<Esc>.

2. Undo a change

Press u to undo the second line. You are now back to 'This is the first version.'.

3. Create a new branch

Type oThis is a new branch.<Esc>. You have now created a new undo branch.

4. View undo history

Type :undolist and press Enter. Observe the different undo points and their numbers.

5. Navigate to an older branch

From the :undolist output, identify the undo point that corresponds to 'This is the second version.' (it will likely be a lower number than your current state). Type :undo {N} where {N} is that undo point number. You should now see 'This is the second version.' again, effectively 'undoing an undo' from a different branch.