Using Per‑Project Persistent Undo in Vim for Secure Cross‑Session Editing
Learn how to set up a per‑project undo directory in Vim so your edit history survives SSH reconnects, with security tips and a worked example.
12 Feb 2026, 11:15 UTC

Problem: losing undo history when you jump between sessions on a remote server
When you edit a file over SSH, make a few changes, then disconnect, you lose the ability to undo those edits once you reconnect and reopen the file. This forces you to redo work or rely on version control just to see what changed.
Thesis: a per‑project undo directory gives you session‑spanning undo while keeping the undo data private
By telling Vim to write undo files to a directory that lives inside the project tree (or a dedicated private folder) and securing that directory, you keep the undo history across editor restarts without exposing it to other users on the same system.
How persistent undo works with a dedicated directory
When set undofile is on, Vim serializes the undo tree to a file whose name is a percent‑encoded copy of the edited file’s path. The file is placed in the directory given by undodir. On the next read of the same buffer Vim loads that file before allowing any edits, so the undo history is available immediately.
Configuration: a project‑local undo folder
- Decide where to store undo files. A common choice is a hidden folder inside the project, e.g.,
.vimundo. - Add the following lines to your
~/.vimrc(orinit.vimfor Neovim) so they are applied to every buffer:
set undofile " enable persistent undo
set undodir=$HOME/.vim/undo// " fallback global directory
Then, to override the location for a specific project, create a file .vimrc in the project root (or use a modeline) containing:
set undodir=.vimundo// " project‑relative undo directory
Make sure the directory exists and is only readable/writable by you:
mkdir -p .vimundo
chmod 700 .vimundo
Reload the configuration (:source $MYVIMRC) or restart Vim.
Worked example: editing a script across two SSH sessions
- Open the project, ensure the
.vimundodirectory exists withchmod 700. - Edit
src/main.py: add a function, change a variable, save (:w). - Quit Vim (
:q). - In the shell, list the undo directory:
ls -la .vimundo
You should see a file whose name looks like %home%user%project%src%main.py (percent‑encoded path).
- Reconnect via SSH, start Vim again and open
src/main.py. - Press
urepeatedly. You will step back through the edits you made before you quit, confirming that the undo history survived the session break.
Trade‑off and practical limits
- Disk usage: each edit adds data to the undo file. Very large files or many tiny changes can make the undo directory grow quickly.
- Sensitive data: undo files contain the exact text of your edits, including any passwords or API keys you might have typed. If the undo directory is world‑readable, that information is exposed.
- Mitigation: limit the number of stored undo levels with
set undolevels=500(or another value) to bound the size of each undo file, and periodically clean old files (e.g.,find .vimundo -type f -mtime +30 -delete) or encrypt the folder using your filesystem’s encryption facilities.
Actionable closing
- Add the global
set undofileand fallbackundodirlines to your vimrc. - In each project, create a hidden undo folder (
.vimundo) and setset undodir=.vimundo//via a project‑local vimrc or modeline. - Secure the folder:
chmod 700 .vimundo. - After editing and saving, verify that a new undo file appears (
ls -la .vimundo). - Close and reopen the file; press
uto confirm you can undo pre‑exit changes. - If the undo directory starts consuming too much space, adjust
undolevelsor schedule a cleanup.
With these steps you get reliable, session‑spanning undo in Vim while keeping the undo data under your control.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.