Some word processors and text editors auto-save the files we're editing from time to time, which is very convenient for surviving from nasty crashes, etc.
Is there a way to make Vim auto-save our files after a specific interval?
Vi and Vim Stack Exchange is a question and answer site for people using the vi and Vim families of text editors. It only takes a minute to sign up.
Sign up to join this communityThere isn't a builtin option, although :help 'autosave'
(in todo.txt) refers to a description of what such an option could do.
One possible way to implement this is to use the CursorHold
autocommand event. This event is triggered when the user hasn't pressed a key for 'updatetime'
milliseconds.
autocmd CursorHold * update
The :update
command only saves the buffer if it is modified. If you also wanted this to happen while insert mode is active, CursorHoldI
could be added to the event list.
autocmd CursorHold,CursorHoldI * update
Another alternative is the 'autowrite'
option, which will save the buffer before executing an external command (useful for saving before running :make
) or switching to a different buffer.
:help 'updatetime'
to learn more about it
autocmd CursorHold * silent update
.
Vim does have an auto-save feature, but it saves it to the "recovery" file.
When you edit a document, e.g. MyFile.txt
vim will create the revovery file .MyFile.txt.swp
. If your system were to crash, or your session were to die, then you can reconnect, and recover from essentially where you left off, by typing:
vim -r MyFile.txt
This will open the file for editing, and recover the last changes you made to it.
You can then save the recovered version the normal way :w
.
Unfortunately, when you exit vim, it will leave the .MyFile.txt.swp
around, and you need to remove it manually:
rm .MyFile.txt.swp
See "Recovery" Man page Also Chapter 11
:wq
or :q!
or ZZ
or etc.), swap files should automatically be removed.
I made a plugin vim-autosave which uses Vim 8 feature of Timers to periodically save your buffers.
I make my Vim save everything every time focus is lost.
autocmd FocusLost <your-patterns-here> silent! wall
My patterns are pretty long and I use them in several autocmds but for completeness this is what it looks like:
if exists(':keeppatterns')
let s:keeppatterns = 'keeppatterns '
else
let s:keeppatterns = ''
endif
augroup AutoSaveGroup
" :help file-pattern has some info,
" but some of it is is buried in the PATTERNS section of usr_40.txt
let s:autoPattern = "*.{c,h,[ch]pp,[acjt]s,inl,cg,cgfx,fx,py,bat,cmd,jam,vim,yml,yaml,vsprops,erb,rb,html,htm},SCons*,*vimrc"
autocmd!
execute "autocmd FocusLost" s:autoPattern "silent! wall"
execute "autocmd BufWritePre" s:autoPattern s:keeppatterns . 'call FixFormatting(expand("<afile>"))'
execute "autocmd FileChangedRO" s:autoPattern "silent !p4 edit %:p"
execute "autocmd FileChangedRO" s:autoPattern "write!"
autocmd FocusLost *.txt silent! wall
augroup END
As others have indicated, vim has a swap file (.swp) that will be created where ever your original file is, but in your .vimrc file, you can set the .swp directory.
You'll need to create the directory with mkdir
and then set your .vimrc to that location.
set backup " make backup files
set backupdir=~/.vim-tmp,~/.tmp,~/tmp,/var/tmp,/tmp
The vim-workspace plugin has a fairly customizable auto-save feature that may suit your needs. By default, it enables autosave when in a workspace session (its main feature), but you can set it to always autosave if that's all you're looking for (let g:workspace_autosave_always = 1
).
Try to saves the buffer whenever text is changed:
autocmd TextChanged,TextChangedI <buffer> silent write
This works for me.
TextChanged
("After a change was made to the text in the current buffer in Normal mode.") over CursorHold
("When the user doesn't press a key for the time specified with 'updatetime'"). I would be curious to understand the advantages of one or the other method. TextChanged
feels more responsive, as I don't have to wait for the update time delay, and can close the file immediately after an edit.
Sep 22 at 9:48
Put this on your vimrc:
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => vim-autosave
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Save on lost focus/exit
autocmd FocusLost,VimLeavePre * silent! w
" Also, save once per minute if there are changes
let g:autosave_seconds = 60
au BufRead,BufNewFile * let b:start_time=localtime()
au CursorHold * silent! call UpdateFile()
function! UpdateFile()
if ((localtime() - b:start_time) >= g:autosave_seconds)
update
let b:start_time=localtime()
endif
endfunction
au BufWritePre * let b:start_time=localtime()
An indirect way to achieve autobackup is to enable set undofile
. Every change of an opened file is saved there, multiple undo levels, even after a file is closed and vim exited. I consider it very practical, better than autosave.
Yes it is, but it is but unfortunately not built in to Vim itself. You can use an autocommand that calls a function to autosave the file:
" auto save file when it is modified
augroup auto_save
autocmd!
" call save function
autocmd BufModifiedSet * call AutoSave()
augroup end
" save function that is called when buffer is modified
function AutoSave()
if (bufname() != "" && &buftype == "" && &filetype != "" && &readonly == 0)
silent write
" prevent empty, readonly, etc... buffers from being saved
else
endif
endfunction