Undo, Redo, and Registers
Neovim has one of the most powerful undo systems of any editor — a persistent, branching undo tree (not just a linear history). Registers are Vim's multi-clipboard: 26 named slots plus special-purpose registers.
Undo and Redo (Basic)
| Key | Action |
|---|---|
u | Undo last change |
Ctrl+r | Redo |
U | Undo all changes on current line |
5u | Undo last 5 changes |
The Undo Tree
Vim/Neovim stores undo history as a tree, not a list. If you undo, then make a new change, the old redo branch is preserved — you can navigate back to it.
Change 1 → Change 2 → Change 3
↓
Undo to 2 → New Change 4 (branch!)
↓
Change 3 still accessible via :undolist
Navigating the Undo Tree
:undo → undo one level
:redo → redo one level
:undolist → show branches in undo tree
:earlier 1m → go to state 1 minute ago
:later 30s → go forward 30 seconds
:earlier 5f → go back 5 file saves
:earlier 10m is incredibly useful when you've been editing and want to see the state from 10 minutes ago.
Persistent Undo
Configure undo history to persist across sessions:
-- Persistent undo
vim.opt.undofile = true
vim.opt.undodir = os.getenv("HOME") .. "/.config/nvim/undo"
mkdir -p ~/.config/nvim/undo
Now undo history survives file close and reopening.
Registers — The Multi-Clipboard
Registers are named storage slots for text. Think of them as 35+ separate clipboards.
Viewing Registers
:registers → show all register contents
:reg a b c → show registers a, b, c
The Most Important Registers
| Register | Name | What's stored |
|---|---|---|
" | Unnamed | Last delete/yank (default) |
0 | Yank | Last yank only (not delete) |
1-9 | Numbered | History of deleted text |
a-z | Named | Manually saved text |
A-Z | Named (append) | Appends to named register |
+ | System clipboard | OS clipboard |
* | Selection | Primary selection (Linux X11) |
_ | Black hole | Discards (no register update) |
/ | Search | Last search pattern |
: | Command | Last : command |
. | Dot | Last inserted text |
% | Filename | Current file name |
Using Registers
Yanking to a specific register:
"ayiw → yank inner word into register 'a'
"Ayiw → APPEND inner word to register 'a'
"by} → yank to next paragraph into register 'b'
"+yy → yank line to system clipboard
Pasting from a specific register:
"ap → paste from register 'a'
"+p → paste from system clipboard
"0p → paste last yank (not delete)
".p → paste last inserted text
In Insert mode:
Ctrl+r a → insert contents of register 'a'
Ctrl+r + → insert from system clipboard
Ctrl+r 0 → insert last yank
The Yank Register ("0)
This is critically important: the 0 register always contains your last yank, even if you've deleted since then.
Scenario:
yiw → yank "Alice" into " and 0 registers
dw → delete next word → pollutes " register
"0p → paste "Alice" (still in 0 register)
Without "0p, p would paste the deleted word, not what you yanked.
The Black Hole Register ("_)
Deletes without polluting any register — true "discard":
"_dd → delete line without storing it
"_diw → delete word without replacing clipboard
"_dG → delete to end of file without overwriting clipboard
Named Registers for Workflow
# Copy a function to register 'f'
"fyaB → yank around brace block to 'f'
# Move to destination, paste
"fp → paste the function
# Collect multiple items
"ayiw → first item to 'a'
"byiw → second item to 'b'
# ... paste later
"ap "bp
The Full Undo + Registers Workflow
1. Yank what you need: yiw (stored in " and 0)
2. Delete something else: dd (overwrites ")
3. Paste your yank: "0p (safe, uses yank register)
4. Undo the paste: u (clean)
5. Redo: Ctrl+r