44

I don't want to know about why you should not auto-save or there is swap file etc or whatever reason to not auto-save.

I simply want to auto-save the current working file to save in every 1 second in vim.

How can I achieve this?

Beryllium
  • 12,808
  • 10
  • 56
  • 86
user537488
  • 927
  • 3
  • 8
  • 15
  • For 2021 readers: If you're using Coc.nvim too please read my answer. I'm a Vim expert. – NeoZoom.lua May 03 '21 at 13:44
  • Another plugin: https://github.com/907th/vim-auto-save ■ note that most solutions below will create weird entries in the undo history. There seems to be no good solution, refer to https://github.com/907th/vim-auto-save/issues/53 -- although for my purpose (recompile Typst as you type in vim) I don't actually need it to write to the current file so I make it write to another file instead. – user202729 Mar 25 '23 at 14:25

4 Answers4

76

This saves the buffer whenever text is changed. (Vim 7.4)

autocmd TextChanged,TextChangedI <buffer> silent write

Sameer
  • 2,435
  • 23
  • 13
10

When you start reading a file, set a buffer variable to the current time:

au BufRead,BufNewFile * let b:save_time = localtime()

Set an event to check if enough time has elapsed since the last save and update if not:

au CursorHold * call UpdateFile()

Set the auto-save period, in seconds:

let g:autosave_time = 1

Define a function to save the file if needed:

" save if needed / update the save_time after the save
function! UpdateFile()
  if((localtime() - b:save_time) >= g:autosave_time)
      update
      let b:save_time = localtime()
  else
      " just debugging info
      echo "[+] ". (localtime() - b:save_time) ." seconds have elapsed so far."
  endif
endfunction

Then, to reset the save time explicitly:

au BufWritePre * let b:save_time = localtime()

I have not tested the above on vim 7.0 and later. Also, the CursorHold event is unlikely to be enough for such a small auto-save period (it also doesn't trigger when recording) - maybe you should also call UpdateFile() on CursorMoved as well.

Also, consider using swap files. By default a swap file is writen to after either 200 characters typed or 4 seconds of inactivity. Recovery from swap is quite simple and maybe more reliable, in case something goes wrong.

Michael Foukarakis
  • 39,737
  • 6
  • 87
  • 123
  • 3
    It seems that this feature is already planned for next versions of Vim (on Vim 7.3 `:help autosave` displays from `todo.txt`). For the moment I believe there are no suitable autocmd/event to write a vimscript to perform save for every second. But solution proposed by Michael should work for most of cases, because even if it doesn't perform saves when cursor is not moved, it is not very likely that you will perform any changes without moving the cursor. – mMontu Aug 09 '11 at 16:25
  • 2
    In vim 7.4, the built-in autosave feature is still listed under improvements to be added in future versions. – joelostblom Feb 19 '16 at 03:08
4

For Readers in 2021 and You're using CoC.nvim Plugin

Use this which is compatible to Coc.nvim:

autocmd InsertLeave * if &readonly==0 && filereadable(bufname('%')) \
                       | silent update | endif

The accepted answer will cause the autocompletion fails.

Peace.


Showing some UI to prove I love (neo)Vim(-nightly): (Clickable, many others see my profile intro.)

NeoZoom.lua
  • 2,269
  • 4
  • 30
  • 64
3

The vim-workspace plugin has a fairly customizable auto-save feature that may suit your needs (with autoread so you get last writer wins behaviour). You can set it to always autosave (by default, it only autosaves while in a workspace session) and set your updatetime accordingly.

let g:workspace_autosave_always = 1
updatetime=1000
jaybay
  • 31
  • 2