Tip 24 | Making Undo Persist Between Sessions |
The undo command is a lifesaver when you need to revert changes that didn’t work out. Typically, you can only undo changes that were made to a file during the current editing session. By enabling Vim’s ‘undofile’ option, you can make undo history persist between editing sessions.
Open the green-bottles.txt file from the source code that accompanies this book in Vim:
| 10 green bottles hanging on the wall. |
Use the <C-x> command to decrement the number at the start of the line. Now you can use u to undo the change and <C-r> to redo it. If you quit Vim and then reopen the same file, what do you expect to happen when you use the u command?
Your undo history is usually lost when you quit your text editor. If you enable the ‘undofile’ option, then Vim will write your undo history to a hidden file, making it persist between editing sessions (:help persistent-undo). To enable this feature, add this line to your vimrc file then reload it:
| set undofile |
Switch back to the green-bottles.txt file and use the <C-x> command again to decrement, then for good measure, use . a couple of times to repeat the change. Now quit Vim and reopen the same file. You should be able to use u to undo those changes. Pretty cool, huh?
With the ‘undofile’ option enabled, Vim records the undo history for a file by writing to a hidden file in the same directory. In the previous example, the green-bottles.txt file would have its undo history written to a file called .green-bottles.txt.un~. This can lead to a proliferation of hidden files mixed into your working directory.
To avoid this, use the ‘undodir’ option to specify a directory where your undo files will be saved. Add this line to your vimrc, then reload your vimrc:
| set undodir=$VIMDATA/undo |
If the path specified in ‘undodir’ doesn’t exist, then persistent undo won’t work. Create the directory by running:
=> | :call mkdir(&undodir, 'p') |
If you’re using Neovim, you can stick with the default ‘undodir’ value of $XDG_DATA_HOME/nvim/undo. You’ll still have to create the directory, though.
Persistent undo is an appealing feature, but it brings some security concerns. Suppose you are using a password manager that uses $VISUAL to launch your preferred text editor. You wouldn’t want to leak your secure password in the form of a hidden undo file.
To avoid this situation, use an autocommand to disable ‘undofile’ locally for files that match a particular pattern. For example, here’s how to disable persistent undo for all files in the /tmp directory:
| augroup vimrc |
| autocmd! |
| autocmd BufWritePre /tmp/* setlocal noundofile |
| augroup END |
You can tweak the file pattern to suit your needs. If you are not familiar with Vim’s autocommands, read Tip 26, Using Autocommands to Respond to Events for an introduction.
Copy this snippet into your vimrc whether you’re using Vim or Neovim:
| set undofile |
| if !has('nvim') |
| set undodir=~/.vim/undo |
| endif |
| augroup vimrc |
| autocmd! |
| autocmd BufWritePre /tmp/* setlocal noundofile |
| augroup END |
This enables persistent undo (except for temporary files) and saves undo files to a designated directory.
3.129.13.201