Vim Tips Wiki
Tip 962 Printable Monobook Previous Next

created July 22, 2005 · complexity basic · author Sylvain Lafleur · version 5.7

Before using Vim, I used a nice little editor called Crimson. It had a nice backup feature that I used all the time. It could be set to automatically backup the current file whenever it was opened up. And all the backups would go to a dedicated backup directory. Furthermore, it kept the full directory structure.


  • I edit the file e:\project1\web\show_users.asp, when i open it up, a backup would be created at f:\vim_backups\E\project1\web\show_users.001
  • If I close my editor and re-open the file again in the afternoon, i would get another backup at f:\vim_backups\E\project1\web\show_users.002

This could lead to a huge number of files but it's easier to retrieve data that is there many times, than to retrieve data that does not exist anymore. Also, a simple zip takes care or any hard drive space issues. I have gone many times to that backup directory because my supervisor wanted the page to go back to what it was two days ago. It's been very useful.

In Vim, however, only 1 backup is created, and it's in the current directory. You can easily modify Vim to save all backups in a single directory, using the :set backupdir option but then you still only have the one latest backup. I created this short set of commands to make Vim have similar functionality as Crimson for backups (it uses date and time instead of numbers for the backup extension). It's the first version, so there might be some bugs, feel free to add/improve to your hearts content. Also, it's set up for Windows Vim right now, but it should be fairly easy to modify it for use on *nix machines.

Script explanation:

step1:set variables
 this_root_backup_dir = the root directory where all backups will be saved
 this_dir = current directory of file you just opened
 this_filename = current filename of file you just opened
 this_drive = drive where the file you just opened is located (Windows)
 this_backup_dir_drive = drive that should exist in this_root_backup_dir
 this_backup_dir = full backup path starting from the root backup directory
step2:check if the necessary drive letter exist in root backup directory, if not create it
step3:check if the necessary directory exist in root backup directory, if not create it
step4:set the new backupdir option for vim

I have these line in my vimrc file:

"Incremental backups, will copy the backup file to a specific backup
"directory and follow the tree structure of the file's directory
"This allows for backup up from multiple drives (on Windows) and easy
"navigation through the backups afterwards.
let g:this_root_backup_dir = 'f:\vim_backups'
let g:this_dir = expand('%:p:h')
let g:this_filename = expand('%')
let g:this_drive = strpart(g:this_dir, 0, 1)
let g:this_backup_dir_drive = g:this_root_backup_dir . '\' . g:this_drive
let g:this_backup_dir = g:this_backup_dir_drive . '\' . strpart(g:this_dir, 3)
"--make DRIVE directory if it doesn't exist
if !filewritable(g:this_backup_dir_drive)
  silent execute expand('!mkdir ' . g:this_backup_dir_drive)
"--make directory under DRIVE if it doesn't exist
if !filewritable(g:this_backup_dir)
  silent execute expand('!mkdir ' . g:this_backup_dir)
"--set new backup dir
execute expand('set backupdir=' . g:this_backup_dir)


Found first bug: Error occurs when you open a file with a space in either the directory or the filename.

I fixed it with a substitute command, replacing all spaces with an underscore.


:let this_dir=expand("%:p:h")
:let this_filename=expand("%")

should become

:let this_dir=substitute(expand("%:p:h")," ","_","g")
:let this_filename=substitute(expand("%")," ","_","g")

See script#563 (rcsvers.vim) for a way to use RCS do do this.

You really should use a version control system for this, like cvs or subversion. Then the text editor doesn't enter into it at all.

You could write very simple hooks to VIM that check in any changes automatically when you enter or exit the editor.

For Windows, try Subversion with TortoiseSVN:

script#89 (savevers.vim) is also pretty good.

augroup backup
    autocmd BufWritePre,FileWritePre * let &l:backupext = '~' . strftime('%F') . '~'
augroup END