20

As the question title mentions. I'm looking to automatically get the file saved as I type in VIM (insert mode).

Is this possible? How to achieve it?

Omar Abid
  • 15,753
  • 28
  • 77
  • 108
  • 1
    Have you checked this? http://vim.wikia.com/wiki/Auto-save_current_buffer_periodically – ctn Jun 28 '13 at 13:03
  • 1
    This might also be helpful: http://vim.wikia.com/wiki/Auto_save_files_when_focus_is_lost – Lars Kotthoff Jun 28 '13 at 13:04
  • 1
    For people using `autocmd CursorHold,CursorHoldI * update` from wikia, note that this has problems with plugins like Telescope that open custom dialogs as the script will attempt to save the dialog. Use `*.*` instead of `*` to exclude non-file buffers. – SOFe Apr 25 '22 at 06:39

7 Answers7

41

I recommend to save the buffer whenever text is changed:

autocmd TextChanged,TextChangedI <buffer> silent write

I found it here. It works for me.

Note (thanks to @Kevin): Unfortunately, it will result in errors if you open vim without opening a file because vim will try to save the text you type but won't have where.

simhumileco
  • 31,877
  • 16
  • 137
  • 115
  • 2
    This is the literal solution. No need to make things complex with plugins. – Iresh Dissanayaka Jul 26 '20 at 08:00
  • 3
    This will result in errors if you open vim without opening a file. – Kevin Oct 17 '20 at 01:51
  • Thank you a lot @Kevin for your important comment! – simhumileco Oct 17 '20 at 07:35
  • 2
    @simhumileco a way around this could be to specify the buffer type. For example `autocmd TextChanged,TextChangedI *.md silent write` – craft Oct 19 '20 at 17:57
  • 4
    As noted by @eric you can check if the buffer is readonly, but this appears to work for verifying that it is backed by a file: `au TextChanged,TextChangedI if &readonly == 0 && filereadable(bufname('%')) | silent write | endif` – J Cracknell Oct 23 '20 at 20:00
  • Instead of `TextChanged`, you can use the `updatetime` & `CursorHold` combination (file will be saved updatetime ms after the cursor stops moving). Put `set updatetime=500` and `au CursorHold,CursorHoldI if &readonly == 0 && filereadable(bufname('%')) | silent write | endif` into your `vimrc`. – Palesz Jun 13 '22 at 21:34
12

You can use AutoSave plugin to perform that:

https://github.com/907th/vim-auto-save

Please notice that AutoSave is disabled by default, run :AutoSaveToggle to enable/disable it.

Aleksei Chernenkov
  • 991
  • 1
  • 8
  • 23
Jayram
  • 18,820
  • 6
  • 51
  • 68
  • 1
    This simply doesn't work. After I enable the autosave, and do some changes to the file, the file is not updated. – Omar Abid Jun 28 '13 at 17:02
  • Agreed with @omar. When I type :AutoSaveToggle I get an error that it doesn't exist, when I type :run AutoSaveToggle it does nothing. – Brettins Nov 16 '16 at 19:15
  • After further investigation, it I think this is a communication issue. The first line of this answer about using :AutoSaverToggle REQUIRES the plugin vim auto save to work. This was not my interpretation of the message from Jayram, especially because of the second line, which implies that it is a native VIM command and in addendum you could also use the plugin. However, the plugin is required for this command. – Brettins Nov 16 '16 at 19:27
  • @Brettins Yes, `:AutoSaveToggle` is a part of the `AutoSave` plugin. It is not a native Vim command! – Aleksei Chernenkov Mar 10 '17 at 12:04
  • Finally found how to install this plugin: need to config the plugin in the .vimrc, and then run `:PluginInstall` without specifying any plugin name. – Deqing Mar 21 '23 at 07:48
5

This will handle read-only buffers (like netrw) and undetected filetypes. Using TextChangedI instead of InsertLeave seems to cause a write for every character typed in insert mode, which may or may not be what you want.

augroup autosave
    autocmd!
    autocmd BufRead * if &filetype == "" | setlocal ft=text | endif
    autocmd FileType * autocmd TextChanged,InsertLeave <buffer> if &readonly == 0 | silent write | endif
augroup END
Eric
  • 71
  • 1
  • 3
  • 2
    Could you explain each line of your code? – NeoZoom.lua May 01 '21 at 17:39
  • 1
    line 2: clear all autocmds in this group line 3: if the filetype is unset, set it to "text" line 4: When leaving insert, and the text changed, and the file is writable, save the file – Eric May 18 '21 at 14:08
2

There is no native support for auto-saving in Vim. But you can use vim-auto-save plugin to perform that.

This plugin auto-saves in normal mode only by default, but there is a section in it's README which describes how to configure the plugin to save in insert mode too. Hint: you should configure the plugin to auto-save on CursorHoldI and/or TextChangedI Vim events.

Please, refer to the plugin documentation on how to install and use it.

Aleksei Chernenkov
  • 991
  • 1
  • 8
  • 23
1

Don't know if someone mentioned this. Autosave Per File Type

( in this case it is for a Markdown *.md file)

autocmd BufNewFile,BufRead *.md :autocmd TextChanged,TextChangedI <buffer> silent write

This will write the contents of the file the moment they are modified but only for Markdown (*.md) files.

mlongval
  • 31
  • 4
0

907th/vim-auto-save auto saves file. But if your .vimrc depends on write event, then it could have issue.

Recently, I notice https://github.com/chrisbra/vim-autosave, which saves files to a backup dir, which sounds promising if your .vimrc depends on write event.

kgflying
  • 194
  • 9
0

Using a function with logic to handle read only buffers and empty buffers in tandem with a autocommand works pretty well:

" 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

The autogroup auto_save contains an autocommand that calls AutoSave(). It is executed whenever the current buffer is modified(see :help BufModifiedSet). The AutoSave() function writes the buffer only if it is writeable, it is not blank, and it(the buffer) has a file type.

unrealapex
  • 578
  • 9
  • 23