- I've scrapped the "shell" method, as it was too dysfunctional. It stopped insert mode and left zombie processes. Look at this posts's revision history is you really want to see it anyway.
- I've made a plugin out of this: auto_autoread.vim. At the moment, it's effectively the same as the code below, but I would recommend you use the plugin as this is likely to receive updates.
To answer this question, we must first understand what the
does, and more importantly, what it doesn't do.
doesn't have a lot of information on this, it just says "a file has been
detected to have been changed outside of Vim". How does Vim detect that a file is
changed? On certain actions, Vim checks the modification time of the file.
: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 (
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
- 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
check_timestamps() functions, and locations where
need_check_timestamps is set to
I may have missed some events, but the key thing to remember is that Vim only
checks if the file is modified in a very limited set of cirsumstances. It
certainly doesn't "poll" the file for changes ever n seconds, which is
basically what you're after.
So, for your purpose,
set autoread is not enough.
This schedules a Python thread to run in the background, it will run
:checktime every n seconds. If
autoread is enabled, this will reload the
buffer from disk, else it will just warn.
This requires that Vim has
:version. It should work
on all platforms (including Windows).
python << EOF
import time, vim
try: import thread
except ImportError: import _thread as thread # Py3
vim.command('checktime') # Run the 'checktime' command
vim.command('redraw') # Actually update the display
You can start this off by using
:call AutoreadPython(); you can of course do
this in an autocmd; for example:
autocmd *.c call AutoreadPython()
There are actually more methods, for example you could use a tool such as
entr or the Python
gamin module to
monitor a file for changes,
:checktime also checks all buffers if it's not
given any arguments, this could be improved on by only checking a single buffer
or a certain file.
However, this answer is already rather long :-) These method should (hopefully!)
work fine for most scenarios, or should be easily adaptable to your scenario.
PS. I also tried to use Ruby, but unfortunately Ruby threads (using
don't run in the background like Python does, so I wasn't able to get this to
work (perhaps there is another way, though?)