Auto-reloading a file in VIM as soon as it changes on disk

34

11

Assuming that a file doesn't have unsaved changes in the VIM buffer, I'd like it to reload automatically if the file changes on disk. The most frequent use case for this is when I update the working copy in which the file resides.

How can I achieve this?

GJ.

Posted 2010-08-27T13:13:54.800

Reputation: 8 151

1I think this is what you mean, but my specific use case is when I check out a different git branch or commit, I want vim to reload the file. – Nathan Long – 2016-02-12T18:56:07.083

Answers

33

In your ~/.vimrc:

set autoread

Benjamin Bannier

Posted 2010-08-27T13:13:54.800

Reputation: 13 999

9

Generally autoread will only trigger after executing an external command. This answer details the solutions.

– Tom Hale – 2017-08-01T05:12:03.507

This doesn't work Follow the @TomHale link for a detailed answer that does – JonnyRaa – 2017-11-13T10:35:09.813

11

This is what worked for me

set autoread                                                                                                                                                                                    
au CursorHold * checktime  

The first line wasn't enough by itself. You can put in you .vimrc

credit to Phan Hai Quang

ErichBSchulz

Posted 2010-08-27T13:13:54.800

Reputation: 281

The autocmd shouldn't be necessary--checktime is supposed to run internally at the same time the CursorHold event is triggered. In other words, you're just making Vim do a second checktime. – Heptite – 2016-06-18T16:37:05.673

For me it is necessary. Best solution I've found after lots of research. @Heptite, do you have chapter and verse for your assertion? – Tom Hale – 2017-08-01T05:19:55.590

1@TomHale I've reviewed the Vim docs and it doesn't explicitly say, as far as I can tell, but ":help timestamp" would seem to indicate I'm the one in error, and that Vim only performs the check on specific events, so the autocmd could be necessary to cause it to check more frequently. – Heptite – 2017-08-01T16:17:10.547

5

Autoread does not work correctly. The following works for me:

You need to first install the script from here.

I got the best results by calling the setup function directly, like so.

let autoreadargs={'autoread':1} 
execute WatchForChanges("*",autoreadargs) 

The reason for this, is that I want to run a ipython/screen/vim setup.

You can easily convert this into an enhanced version of view.

script the process..

mkdir -p ~/bin
cat <<`OUT` > ~/bin/vimviewer
#!/usr/bin/env sh
exec vim -n --cmd "source /home/bryan/.vim/.vimrc.watchforchanges | let autoreadargs={'autoread':1} | execute WatchForChanges('*',autoreadargs)" $@
`OUT`

chmod 755 ~/bin/vimviewer
vimview test.txt

Bryan Hunt

Posted 2010-08-27T13:13:54.800

Reputation: 183

1If you're using one of the vim GUIs such as gVim or MacVim then the autoread command integrates fine with the rest of the environment. E.g. editing the file in some other program, another editor or from source control, then switching back to vim will autoread the updated files. The problem seems to be with how the terminal version of vim integrates. The terminal version can't tell when you switch between programs either in the GUI or using terminal multiplexers like tmux, so it fails to autoread at relevant times. It would be nice if vim would just subscribe to relevant file-system events. – bames53 – 2014-05-03T23:31:29.973

3

vim-autoread plugin has worked for me so far:

vim-autoread

Automatically causes vim to reload files which have been written on disk but not modified in the buffer since the last write from vim. This enables a file open in vim to be edited using another application and saved. Upon returning to vim, as long as you haven't modified the file since the last change, the file will be automatically updated to reflect the changes made on disk, as though you had pressed :e manually.

Wojtek Kruszewski

Posted 2010-08-27T13:13:54.800

Reputation: 1 004

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review

– Burgi – 2017-05-05T13:34:43.357

@Burgi I've added plugin description that explains how it solves the problem. – Wojtek Kruszewski – 2017-05-05T14:01:36.850

I tried it but I have to type a navigation command (like j) to see the effective update. I created an issue here about this: https://github.com/djoshea/vim-autoread/issues/3

– Martin Delille – 2018-12-19T13:34:38.683

3

from this answer (refering to an answer by PhanHaiQuang and a comment by @flukus)

One can run this oneliner from ex (whithin vim) when needed (or put each command in vimrc, for when log-files are opened.)

:set autoread | au CursorHold * checktime | call feedkeys("lh")

Explanation:
- autoread: reads the file when changed from the outside (but it doesnt work on its own, there is no internal timer or something like that. It will only read the file when vim does an action, like a command in ex :!
- CursorHold * checktime: when the cursor isn't moved by the user for the time specified in 'updatetime' (which is 4000 miliseconds by default) checktime is executed, which checks for changes from outside the file
- call feedkeys("lh"): the cursor is moved once, right and back left. and then nothing happens (... which means, that CursorHold is triggered, which means we have a loop)

eli

Posted 2010-08-27T13:13:54.800

Reputation: 436

lh does not do nothing, if the cursor is at the last position on the line, lh will change its location. – Mahmoud Al-Qudsi – 2018-04-25T23:41:21.873

Exactly, thats the point. The file is reloaded with the minimum of interaction or changes to the file. You could jump to the last or first line if you want (just replace lh with gg or G), but the goal here, is just to reload the file in vim, and thats whats done by this one-liner, nothing more. What Do you like to be done here? – eli – 2018-04-26T09:01:57.207

@MahmoudAl-Qudsi ... meaning, that "lh" just triggers the CursorHold - action (I mentioned that in the Explanation), which then again triggers the autoread – eli – 2018-04-26T09:42:17.050

1

There are some plugins listed here that might work depending on your version of Vim.

Another approach is to periodically send the checktime command to vim from an external process. Here's a ShellJS script to do this (requires shelljs-plugin-sleep, NeoVim, and nvr)

while (true) {
  sleep(15);
  var servernames = exec('nvr --serverlist').trim().split('\n');
  if (!servernames.length || !servernames[0]) {
    continue;
  }
  servernames.forEach(
    (sn) => exec(`nvr -c "checktime" --servername ${sn}`) );
}

Andrew

Posted 2010-08-27T13:13:54.800

Reputation: 232