How to Undo and Redo in Vim / Vi
In this tutorial, we will show you how to Undo and Redo in Vim / Vi. Mastering text editing in Linux environments requires familiarity with powerful tools like Vim and Vi. Among the essential skills for efficient text manipulation is understanding how to undo and redo changes. Whether you’re correcting a typo, testing alternative edits, or recovering from accidental deletions, Vim’s robust undo/redo system offers capabilities beyond what most text editors provide. This comprehensive guide explores Vim’s undo and redo functionality, from basic commands to advanced techniques that will transform your editing workflow.
Understanding Vim’s Change Tracking System
Before diving into specific commands, it’s important to understand how Vim tracks changes. This knowledge forms the foundation for effectively using the undo and redo features.
How Vim Records Changes
Vim doesn’t simply record a linear history of changes. Instead, it creates “entries” in an advanced undo system. Each entry represents a complete action that modified the text. When you enter insert mode, make changes, and return to normal mode, Vim records all those modifications as a single undo entry. This means pressing undo once will reverse all the typing you did during that insert session.
Vim’s Tree-Based Undo System
Unlike most text editors that offer a simple linear undo history, Vim implements a tree-based structure for tracking changes. This means your editing history can branch into different paths, allowing you to explore alternative edits without losing your original work. This powerful feature becomes particularly useful in complex editing scenarios where you might want to try different approaches to solving a problem.
Basic Undo Commands in Vim
Let’s start with the fundamental commands for undoing changes in Vim.
Entering Normal Mode First
Before using any undo command, you must be in normal mode. This is a critical first step that new Vim users often forget.
- Press
Esc
to ensure you’re in normal mode - Now you can use undo commands
The ‘u’ Command
The simplest and most common way to undo changes in Vim is by using the u
key in normal mode.
u
Pressing u
will undo the most recent change. Each subsequent press undoes the next most recent change. This command is universal in Vim/Vi and functions in the same way across different versions.
Alternative Undo Commands
Vim offers several equivalent ways to undo changes:
:u
:undo
These command-line alternatives perform the same function as pressing u
in normal mode. Additionally, you can undo a specific change by providing a number:
:undo N
For example, :undo 3
will undo to the state after the third change.
The ‘U’ Command
The uppercase U
command is different from the lowercase u
. It undoes all recent changes made to the current line, rather than a single change. This can be useful when you’ve made multiple edits to one line and want to revert all of them at once.
However, be cautious with this command – once you move to a different line, you can no longer use U
to undo the changes to the previous line.
Basic Redo Commands in Vim
Knowing how to restore changes after undoing them is equally important.
The ‘Ctrl+r’ Command
To redo a change that you’ve just undone, press Ctrl+r
in normal mode. This command reverses the most recent undo operation, effectively restoring the change you just removed.
Ctrl+r
Each time you press Ctrl+r
, Vim redoes one more change in sequence. This allows you to step forward through your undo history to restore multiple changes.
Alternative Redo Commands
You can also use the command-line mode to redo changes:
:redo
This command performs the same action as Ctrl+r
but can be executed from Vim’s command line.
Redoing After Undoing Multiple Changes
If you’ve undone multiple changes and want to redo them all, you’ll need to press Ctrl+r
repeatedly to step forward through your undo history one change at a time. Remember that redo only works immediately after an undo operation. If you make a new change after undoing, you won’t be able to redo the previously undone changes through the standard redo path.
Performing Multiple Undo and Redo Operations
For efficient editing, Vim allows you to perform multiple undo or redo operations at once.
Numeric Prefixes for Undo
To undo multiple changes with a single command, precede the undo command with a number:
5u
This example undoes the 5 most recent changes. The numeric prefix can save you time when you need to undo several changes at once.
Numeric Prefixes for Redo
Similarly, you can redo multiple changes at once:
5Ctrl+r
This command redoes 5 previously undone changes in sequence. Using numeric prefixes helps streamline your editing workflow by reducing the number of keystrokes needed.
Strategic Use of Multiple Operations
When working with complex documents, strategically using these multiple undo and redo operations can significantly improve your editing efficiency. For example, if you know you need to revert exactly 10 changes, using 10u
is much faster than pressing u
ten times.
Understanding and Using Undo Branches
One of Vim’s most powerful features is its branched undo system, which allows for non-linear editing history.
What Are Undo Branches?
An undo branch is created when you undo one or more changes and then make a new change. Instead of losing the undone changes forever (as in most editors), Vim retains them in a separate branch of your editing history. This creates a tree-like structure of changes rather than a simple linear history.
Creating New Branches
Branches form automatically when you:
- Make some changes to your document
- Undo one or more of those changes
- Make a new change
At this point, Vim has created a branch in your editing history. The original sequence of changes is preserved, even though you’ve now started a new editing path.
Navigating Between Branches
To navigate between different branches in your undo tree, you’ll need to use special commands:
g- // Move to older text state
g+ // Move to newer text state
These commands allow you to move through the text states chronologically, regardless of which branch they belong to.
Viewing and Navigating Undo History
Vim provides tools to view and navigate your complete editing history.
The ‘:undolist’ Command
To see a list of your available undo states, use:
:undolist
This displays information about all saved undo states, including:
- Number: The change number
- Changes: The number of changes made
- When: The time when the change was made
- Saved: Whether the file has been saved to disk and where
Jumping to Specific Undo Points
Once you have the undo list, you can jump directly to a specific point in your editing history:
:undo {number}
Replace {number}
with the change number from the undolist. For example, :undo 15
jumps directly to the state after the 15th change was made.
Practical Applications
This feature is particularly useful for:
- Recovering text from an earlier version of your document
- Comparing different versions of your text
- Exploring alternative editing approaches without committing to them
Time-Based Undo and Redo
Vim offers unique time-based undo and redo commands that allow you to navigate to specific points in time.
The ‘:earlier’ Command
The :earlier
command lets you jump back to how your text looked a specific amount of time ago:
:earlier 5m // Go back to how text was 5 minutes ago
:earlier 1h // Go back to how text was 1 hour ago
:earlier 1d // Go back to how text was 1 day ago
You can also go back a specific number of changes:
:earlier 10 // Go back 10 changes
The ‘:later’ Command
Conversely, the :later
command moves forward in time:
:later 5m // Go forward to how text was 5 minutes later
:later 10 // Go forward 10 changes
Combining Time-Based Navigation with Regular Undo/Redo
These time-based commands can be combined with regular undo and redo operations for maximum flexibility. For example, you might use :earlier 10m
to go back to how your file looked 10 minutes ago, then use regular undo and redo commands to make fine-grained adjustments from that point.
Undo and Redo in Different Vim Modes
Understanding how undo and redo work across Vim’s different modes is essential for effective editing.
Normal Mode Considerations
All undo and redo commands must be executed from normal mode. If you’re in insert mode or visual mode, you need to press Esc
first to return to normal mode before using these commands.
Insert Mode and Undo Points
Every time you enter insert mode, make changes, and return to normal mode, Vim creates a single undo entry. This means all the typing you do in one insert session can be undone with a single u
command.
To create more granular undo points during insert mode, you can press Ctrl+g u
. This creates a new undo point without leaving insert mode, allowing for more precise undoing later.
Visual Mode and Undo/Redo
Changes made in visual mode (such as deleting or replacing selected text) create single undo entries. To undo these changes, return to normal mode and use the standard undo commands.
Persistent Undo and Configuration
Vim allows you to save your undo history between editing sessions, providing a powerful way to maintain continuity in your work.
Enabling Persistent Undo
To enable persistent undo, add these lines to your .vimrc
file:
set undofile " Enable persistent undo
set undodir=~/.vim/undodir " Set directory for undo files
This configuration tells Vim to save the undo history to a file, allowing you to undo changes even after closing and reopening a file.
Customizing Undo Levels
You can also control how many changes Vim remembers:
set undolevels=1000 " Set maximum number of changes that can be undone
Increasing this value allows for a deeper undo history but may use more memory. Finding the right balance depends on your editing habits and system resources.
Practical Examples and Common Scenarios
Let’s explore some real-world applications of Vim’s undo and redo functionality.
Recovering from Accidental Deletions
Scenario: You’ve accidentally deleted an important paragraph.
Solution:
- Press
Esc
to ensure you’re in normal mode - Press
u
to undo the deletion - If the deletion happened in multiple steps, continue pressing
u
until the text is fully restored
Exploring Different Edit Paths
Scenario: You want to try two different approaches to rewriting a section.
Solution:
- Make your first set of edits
- Undo to the starting point using
u
- Make an alternative set of edits (this creates a branch)
- Use
:undolist
to see both branches - Navigate between the two versions using
:undo
with the appropriate numbers
Using Undo/Redo for Comparing Versions
Scenario: You want to compare the current text with how it looked before a series of changes.
Solution:
- Use
u
to undo to the earlier version - Examine the text
- Use
Ctrl+r
to redo changes and return to the current version - Repeat as needed to compare different states
Tips and Best Practices
These tips will help you make the most of Vim’s undo and redo capabilities.
Creating Intentional Undo Points
For more control over your undo history:
- Exit insert mode more frequently to create logical undo points
- Use
Ctrl+g u
in insert mode to create an undo point without leaving insert mode - Plan complex edits as sequences of logical steps
Keyboard Efficiency
Optimizing your keyboard workflow:
- Position your hands for easy access to
Esc
,u
, andCtrl+r
- Learn to combine undo/redo with numeric prefixes for faster navigation
- Practice using
:earlier
and:later
for time-based navigation
Common Pitfalls to Avoid
Watch out for these common mistakes:
- Forgetting to return to normal mode before trying to undo
- Using
U
(uppercase) when you meant to useu
(lowercase) - Making new changes after undoing, which creates a branch and prevents simple redoing
- Not saving your work, which can limit your ability to recover changes in some cases
Troubleshooting Undo and Redo Issues
Even experienced Vim users occasionally encounter problems with undo and redo. Here are solutions to common issues.
Changes Cannot Be Undone
If pressing u
doesn’t undo changes:
- Check that you’re in normal mode (press
Esc
to be sure) - Verify that the file is modifiable (
:set modifiable
) - Ensure that you haven’t reached the beginning of your undo history
Redo Not Working
If Ctrl+r
isn’t redoing changes:
- Confirm you haven’t made new changes after undoing
- Check that you’re in normal mode
- Verify you haven’t reached the end of your redo history
Losing Undo History
If your undo history seems truncated:
- Check your
undolevels
setting (:set undolevels?
) - Ensure persistent undo is properly configured if you’re closing and reopening files
- Remember that some operations, like reloading a file, can clear the undo history
Extending Vim’s Undo Capabilities with Plugins
Several plugins can enhance Vim’s already powerful undo system.
Undotree
The Undotree plugin provides a visual representation of your undo history, making it easier to navigate complex branching histories. To install it using Vim-plug, add:
Plug 'mbbill/undotree'
Mundo
Mundo (formerly Gundo) offers a graphical undo tree with a preview of changes:
Plug 'simnalamburt/vim-mundo'
Enhanced Undo Persistence
For more robust persistent undo:
Plug 'chrisbra/vim-autoundo'