select-undo.nvim
July 5, 2026 ยท View on GitHub
Overview
select-undo is a Neovim plugin that enhances undo functionality by allowing users to undo changes selectively. Unlike the default undo command, which reverts changes sequentially across the whole buffer, select-undo enables users to undo specific lines or partial selections without affecting the rest of the file.
For example: if you edit line 10 and then line 50, native undo forces you to revert line 50 first. With select-undo you can select line 10, press gu, and revert only that change - the edit on line 50 stays.
Features
- Selective Line Undo (
gu): revert the newest change within the selected lines; press again to step further back, one change at a time. Safe for sloppy selections - lines whose changes are older stay untouched. - Selective Sweep (
gU): revert the last change of every selected line in one press, even when the lines were edited at different times. - Partial Undo (
gC): revert only the selected characters within a line. - Undo-friendly: A selective undo is a single regular edit, so native
ureverts it in one step. - Persistent Undo: Enables
undofileso undo history survives closing Neovim. - Customizable Keybindings: Default mappings are provided, but users can configure their own.
https://github.com/user-attachments/assets/ce45d5af-971d-4fef-8a31-4d9fbf458019
https://github.com/user-attachments/assets/9075f616-cd54-4760-b563-df258534c0cf
https://github.com/user-attachments/assets/e216aa62-75e9-44b1-897a-32173d8e2407
Installation
Using lazy.nvim
{
"SunnyTamang/select-undo.nvim",
opts = {},
}
Using packer.nvim
use {
"SunnyTamang/select-undo.nvim",
config = function()
require("select-undo").setup()
end
}
Using vim-plug
Plug 'SunnyTamang/select-undo.nvim'
lua require("select-undo").setup()
Usage
Undo entire lines, one change at a time
- Select one or more lines in Visual Mode (
vorV). - Press
guto revert the newest change that touched those lines. - Press
guagain to step the same selection one change further back.
Undo every selected line's last change at once
- Select the lines you edited in Visual Mode.
- Press
gUto revert the last change of each selected line in one press. Use this when you deliberately want everything in the selection undone - it will also revert selected lines you edited earlier and consider "done".
Undo a partial selection
- Select part of a line in Visual Mode (
v). - Press
gCto revert only the selected characters; changes elsewhere on the line are kept.
Customizing mappings
The defaults gu/gU shadow Neovim's built-in visual-mode lowercase/uppercase operators. If you use those, remap the plugin to any keys you like - the built-ins come back automatically:
require("select-undo").setup({
line_mapping = "zu", -- Step undo mapping (frees gu for lowercasing)
sweep_mapping = "zU", -- Sweep undo mapping (frees gU for uppercasing)
partial_mapping = "zcu", -- Partial undo mapping
})
Or disable all default mappings and bind the commands yourself:
require("select-undo").setup({ mapping = false })
vim.keymap.set("x", "<leader>u", ":SelectUndoLine<CR>", { silent = true })
Configuration
Default settings
require("select-undo").setup({
persistent_undo = true, -- Enables persistent undo history (undofile)
mapping = true, -- Enables default keybindings
line_mapping = "gu", -- Step: undo the newest change in the selection
sweep_mapping = "gU", -- Sweep: undo every selected line's last change
partial_mapping = "gC", -- Undo for selected characters
max_history = 100, -- Undo states searched backward per press
})
Limitations
- Partial (character-wise) undo works within a single line; multi-line character selections fall back to line-level undo.
- If the only change touching a character selection rewrote the whole line,
gCrefuses and suggestsguinstead. - Stepping back past a line's creation deletes the line (its oldest recorded state is "not there yet"); native
urestores it in one step. - Restoring deleted content may expand to the whole change so the result stays coherent, but a revert never deletes lines outside your selection.
Development
Run the test suite from the repository root:
nvim --headless -u tests/minimal_init.lua -l tests/run.lua
Contributing
Feel free to open issues or pull requests to improve the plugin.
License
This project is licensed under the MIT License.