Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 44 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nepsilon/003dd7cfefc20ce1e894db9c94749755 to your computer and use it in GitHub Desktop.
Save nepsilon/003dd7cfefc20ce1e894db9c94749755 to your computer and use it in GitHub Desktop.
Auto-backup your configuration files with Vim — First published in fullweb.io issue #71

Auto-backup your configuration files with Vim

Not using versioning on your configuration files and editing them with Vim?

Use Vim’s backup option to automatically keep a copy of past versions. To put in your ~/.vimrc:

"Turn on backup option
set backup

"Where to store backups
set backupdir=~/.vim/backup//

"Make backup before overwriting the current buffer
set writebackup

"Overwrite the original backup file
set backupcopy=yes

"Meaningful backup name, ex: filename@2015-04-05.14:59
au BufWritePre * let &bex = '@' . strftime("%F.%H:%M")

From now on, each time you’ll save a file (hit :w), Vim will save a copy in ~/.vim/backup/ with this syntax your-file.py@2016-10-25.14:58.

This honestly saves my life about once a year 😁.

@melissachang
Copy link

Thank you so much, this saves me a lot of time

@GrayCatCode
Copy link

Thanks for sharing that! 🥇

@sleepy-mouse
Copy link

Great tip, working out of the box!!

@Aeres-u99
Copy link

Its really awesome solution but eventually one will have to manually delete the older backup. is there a way to delete the files older than 7-14 days while initialising vim?

@nepsilon
Copy link
Author

@Aeres-u99 I seldom worry about the size of the backup folder being too big. It's keeping text files so ~1GB of that will store quite a few years of editing. If you need to flush the files for other reasons (security maybe), I'd use a crontab.

@Aeres-u99
Copy link

True indeed! But my question was more from the point of knowing the capabilities of vim :D. Indeed a cron tab will get the job done.

@fourstepper
Copy link

Does this work cross computer as well?

@mgarort
Copy link

mgarort commented Jun 15, 2020

This only backs up what was saved before the new write, so new modifications between the last write and the new write will not be saved.

Does @nepsilon (or someone else!) know how to modify this gist so that it also saves the latest modifications?

I've tried modifying the autocommand event from BufWritePre to BufWritePost and it doesn't work. Not only does it not work, also instead of creating a backup file with the filename filename@2015-04-05.14:59, it creates one with the filename filename~, which really confuses me. Does someone know what's going on here?

@pkfm
Copy link

pkfm commented Aug 30, 2020

@mgarort but new modifications between new and last writes are saved to the original file, so what is the issue?

@mgarort
Copy link

mgarort commented Aug 31, 2020

Hi @pkfm

Yes, but the reason why I want a backup copy is in case the original file is lost by accident.

@samyipsh
Copy link

Thanks for sharing :)

@webcaptcha
Copy link

webcaptcha commented Feb 19, 2022

Should this work with sudo vim file.txt?
Because` when I saved files owned by root (I opened them with sudo vim /etc/hosts for example) it doesn't give me backup file.
@nepsilon

@sql-sith
Copy link

@webcaptcha if you put these settings into your own ~/.vimrc, then, by default, root will not use those settings. For root to use similar settings by default, you would need to muck with a .vimrc file in /root or change system-wide defaults. These are not good options because they mean you are changing something that root interacts with, and breaking root is a really bad thing to risk.

However, sudo has a fix built right into it, just like they were thinking of you. :) Use the --preserve-env parameter (sudo --preserve-env vim) and your environment variables will be retained. For me, this is enough to retain my vim customizations, so I hope it works for you also.

@sql-sith
Copy link

I am not a vim hacker, just a consumer of plugins. I would like to add path information to the backup files, so that I could have names like %home%sql-sith%docs%gists%myfile.txt@2022.03.24.16.04.04.10. This would help me easily distinguish common file names like README.md that are in several different folders.

Is this possible? Alternatively, where is documentation that could help me understand things like au BufWritePre * let &bex = '@' . strftime("%F.%H:%M") so I could just answer my own questions? Thanks.

@mikesmithgh
Copy link

mikesmithgh commented Feb 3, 2023

Updated answer:
@sql-sith I actually overcomplicated it 😂.

From :help backupdir

  • For Unix and Win32, if a directory ends in two path separators "//",
    the backup file name will be built from the complete path to the
    file with all path separators changed to percent '%' signs. This
    will ensure file name uniqueness in the backup directory.
    On Win32, it is also possible to end with "\". However, When a
    separating comma is following, you must use "//", since "\" will
    include the comma in the file name. Therefore it is recommended to
    use '//', instead of '\'.

so you can just add two slashes to the end of backupdir to get the desired result:

set backupdir=~/.backup//
set backup
set backupcopy=yes
set backupext=.bak
set writebackup

and it will look like

%Users%mike%.vimrc.bak

Old answer:

Hi @sql-sith, the documentation can be found here: https://vimhelp.org/options.txt.html#%27bex%27. (Same as :help bex)

https://vimhelp.org/builtin.txt.html#expand%28%29 (:help expand) has the information regarding the meaning of %.

Since this is the extension that is used, you can append to the filename. Something like this should help you:

:echo substitute(expand('%:p'), '/', '%', 'g').'@'.strftime("%F.%H:%M")
%Users%mike%.bashrc@2023-02-02.20:17 

The file would end up looking like this:

.bashrc%Users%mike%.bashrc@2023-02-02.20:17

@vindex10
Copy link

Its really awesome solution but eventually one will have to manually delete the older backup. is there a way to delete the files older than 7-14 days while initialising vim?

maybe something like this could help:

silent execute '!find $HOME/.vimtmp/backup -type f -mtime +7 -delete'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment