:help 'autoread'
doesn't have a lot of information on how it works, but Vim checks if an open file is modified in certain events (it always does this), and will reload it automatically if autoread
is abled.
Specifically, it checks when:
:checktime
is used;
- a buffer is entered;
:diffupdate
is used;
:e
is issued for a file that already has a buffer;
- executing an external command with
!
;
- returning to the foreground (
^Z
, fg
, only if the shell has job control);
for gVim, this is also done when:
- closing the "right-click" menu (either by selecting something, or just by closing it);
- focus is changed (this is what you already noticed);
- closing the file browsers dialog that pops up if you use "file -> open", "file -> save as" from the menu (as well as some other places).
I gathered this information from the Vim source by locating all calls to the buf_check_timestamp()
, check_timestamps()
functions, and locations where need_check_timestamps
is set to TRUE
. This list may be outdated because I looked at it 2015, but at a quick glance it seems to still be (mostly) accurate.
The key thing is that Vim only checks if the file is modified in a very limited set of circumstances. This makes sense, because polling a potentially large number of buffers every n seconds can be rather expensive.
Since Vim 7.4.1578 (March 2016) there are timers, which you can use to run checktime
every n seconds (a previous version of this answer from 2015 used hackish workarounds).
For example, to do this only for certain buffers you can use something like:
set autoread
fun! s:checktime(timer_id)
checktime
endfun
autocmd BufNewFile,BufReadPost xxx
\ call timer_start(3000, function('s:checktime'), {'repeat': -1})
This has the disadvantage of setting a lot of timers, so perhaps a better method is to set one which loops over all the buffers and then sets the timer again (so you don't risk having two run simultaneously):
set autoread
fun! s:checktime(timer_id)
for buf in filter(map(getbufinfo(), {_, v -> v.bufnr}), {_, v -> buflisted(v)})
echom buf
exe 'checktime' buf
endfor
call timer_start(3000, function('s:checktime'))
endfun
call timer_start(3000, function('s:checktime'))
I did notice Vim blinks a bit even if nothing changes; not sure if there's a way to work around that (didn't look at it); so you might want to add it as a command to run only when needed:
set autoread
let s:autoread_timer = -1
fun! s:checktime(timer_id)
checktime
endfun
command! -bang Autoread
\ if <bang>0
\| call timer_stop(s:autoread_timer)
\| else
\| let s:autoread_timer = timer_start(1000,
\ function('s:checktime'), {'repeat': -1})
\| endif
There are many ways to improve on this further, such as enabling it only for the current buffer, more control on how often to run, etc. etc. but the idea should be clear :-)