Everytime I cut out of a session in vim by losing my connection I'm rather filled with dred (and yet I continue to use vim...what a masochistist I must be) because when I open my files again a pile of swap-files are waiting to take a shot at destroying my work. What are the best practices for working with vim swap files? Do you just pick the newest one? If the file works the way you expect, do you just delete the swap files? How do you get rid of them?
-
8Swap files are there to protect your work. Consider using gnu screen.– user859Apr 25, 2018 at 8:53
-
1I don't want to turn the functionality off; it's annoying but as you state useful.– leeand00Apr 26, 2018 at 2:12
-
1I just want to know how to properly use it.– leeand00Apr 26, 2018 at 2:30
-
2@DrEval I use tmux– leeand00Apr 26, 2018 at 6:23
-
6If you use tmux, you shouldn't need to worry about losing your connection: just reattach to your session when you reconnect. You might also be interested in mosh and in @ChristianBrabandt's Recover plugin.– RichApr 26, 2018 at 8:39
2 Answers
Don't Panic!
Recovering files is always safe, because vim never writes any changes until you write them yourself. So recovering from a swap file and then closing without saving won't change anything.
Organize your swapfiles:
Get vim to put all your swap files in the same place, so you always know where they are:
set directory^=$HOME/.vim/swap//
or wherever you prefer. Use //
at the end of the filename makes vim use absolute file paths for the swap file names so you don't get name collisions. Make sure the directory exists, or vim won't use it (it won't create it for you).
Note: This only works on environment variables, if you want to use a vimscript variable then we need to use some :execute
magic:
execute "set directory^=".my_vim_home_var."/swap//"
Diff the differences:
Vim's help suggests a very useful command to use in this situation: :DiffOrig
. It's not a default vim command, so copy the implementation from :h :DiffOrig
into your vimrc. (it's also in $VIMRUNTIME/defaults.vim
if you have vim8). Now, you can recover the file and simply run DiffOrig to get a vimdiff of what's changed from the unmodified version.
If you want to compare the contents of multiple swap files, recover your file with each different swap file, and then write the result to temporary files. Now load up the files and run :diffthis
on each file, make the changes you want, write back to the original file, and delete the temporary and swap files.
Useful commands:
:swapname
: get the name vim is using for the swap file for the current buffer (:h :swapname
)
:recover
: recovers the selected file, same as when you start vim and press R (:h :recover
)
Check out the help:
Vim has an entire section of the user manual on recovery: :usr_11.txt
Vim's reference help on swap files: :h swap-file
, h recovery
Help on the directory option (for setting the swap file location): :h 'directory'
Edit: Modified example for setting directory, as pointed out in comments by @B Layer
-
What about when you end up with multiple swap files? Because of many many dropped connections?– leeand00Apr 27, 2018 at 11:46
-
1I mentioned that in the second paragraph of "Diff the Differencces". Once you've used diffs to determine which changes you want to keep delete all the temporary files and old swap files you made (now you know where all the swap files are). Apr 27, 2018 at 11:54
-
1FYI, you don't need to use
exec
...set directory^=$HOME/.vim/swap//
works fine as long as$HOME
is an initialized environment variable. See:h expand-env
. Also works withdictionary
,undodir
, andbackupdir
to name a few.– B LayerMay 27, 2018 at 0:38 -
Thanks for reminding me about that! I use a vimscript variable in my configuration instead there, hence the execute, and forgot environment variables don't need that. Thinking of it, I should probably just use vim to set an environment variable instead. Jun 8, 2018 at 4:09
-
Thank you very much for pointing out the
//
at the end of the swap file directory avoids collisions. I've been using Vim for years and was never aware of this, and was just wondering "how does Vim avoid collisions?".– NeilGJan 16 at 22:45
Personally, I have turned off swap and backup files, as it tends to create swap files and backup files everywhere and frequently creates conflicts. Vim's persistent-undo has been much more reliable and error-free.
Vim currently has persistent undo, its a much more fine grained method of backup. Every time, you press Esc, the current state of the file is captured.
You can use :undolist
, or plugins like gundo,
or undo-tree to browse your undo history.
To use vim this way:
- create a directory where you editing history for each file will be captured
- tell vim to use that directory
- enable persistent undo
In the shell:
mkdir ~/.vim/undodir
In Vim
set undodir=~/.vim/undodir
set undofile
To turn off swap files: :set noswapfile
-
7There are a couple of pretty big problems with this answer. 1. Persistent undo solves a different problem to swap files (and
'writebackup'
addresses yet another problem). Having persistent undo enabled won't help if your computer crashes. You can argue that swap files are unnecessary for other reasons (modern OS stability, the existence of UPSes), but you haven't done so in this answer. 2. setting'undodir'
doesn't enable persistent undo! You need to set'undofile'
for this– RichOct 18, 2019 at 11:01