refresh changed content of file opened in vi(m)

I have a config-file that I keep open in vim, but that sometimes gets changed on disk, without these changes being reflected on the terminal. Can I refresh the content on the screen without closing and re-opening the file? If so, how?

Asked By: twan163

||

You can use the :edit command, without specifying a file name, to reload
the current file. If you have made modifications to the file, you can use
:edit! to force the reload of the current file (you will lose your
modifications).

The command :edit can be abbreviated by :e. The force-edit can thus be done by :e!

Answered By: Thushi

In addition to manually refreshing the file with :edit, you can put into your ~/.vimrc

:set autoread

to make Vim automatically refresh any files that haven’t been edited by Vim. Also see :checktime.

Answered By: Ingo Karkat

TL;DR

Skip to the Wrap-up heading for the vimrc lines to add to do make your life better.

Manually

Run :checktime

Check if any buffers were changed outside of Vim.
This checks and warns you if you would end up with two
versions of a file.

Automatically

To do automatically load changes, add in your vimrc:

set autoread

When a file has been detected to have been changed outside of Vim and
it has not been changed inside of Vim, automatically read it again.
When the file has been deleted this is not done.

This answer adds a caveat:

Autoread does not reload file unless you do something like run external command (like !ls or !sh etc)

Read on for solutions.

Trigger when cursor stops moving

Add to your vimrc:

au CursorHold,CursorHoldI * checktime

By default, CursorHold is triggered after the cursor remains still for 4 seconds, and is configurable via updatetime.

Trigger on buffer change or terminal focus

Add the following to your vimrc to trigger autoread when changing buffers while inside vim:

au FocusGained,BufEnter * :checktime

Catching terminal window focus inside plain vim

To have FocusGained (see above) work in plain vim, inside a terminal emulator (Xterm, tmux, etc) install the plugin:
vim-tmux-focus-events

On tmux versions > 1.9, you’ll need to add in .tmux.conf:

set -g focus-events on

Wrap-up

Notifications when autoread triggers are also possible.

Here are my vimrc lines to implement all the above:

" Triger `autoread` when files changes on disk
" https://unix.stackexchange.com/questions/149209/refresh-changed-content-of-file-opened-in-vim/383044#383044
" https://vi.stackexchange.com/questions/13692/prevent-focusgained-autocmd-running-in-command-line-editing-mode
    autocmd FocusGained,BufEnter,CursorHold,CursorHoldI *
             if mode() !~ 'v(c|r.?|!|t)' && getcmdwintype() == '' | checktime | endif

" Notification after file change
" https://vi.stackexchange.com/questions/13091/autocmd-event-for-autoread
autocmd FileChangedShellPost *
   echohl WarningMsg | echo "File changed on disk. Buffer reloaded." | echohl None

Thanks to ErichBSchulz for pointing me in the right direction with au CursorHold.

Thanks to this answer for solving the cmdwin issue.

Answered By: Tom Hale

Here’s a lua version for neovim:

-- Triger `autoread` when files changes on disk
-- https://unix.stackexchange.com/questions/149209/refresh-changed-content-of-file-opened-in-vim/383044#383044
-- https://vi.stackexchange.com/questions/13692/prevent-focusgained-autocmd-running-in-command-line-editing-mode
vim.api.nvim_create_autocmd({'FocusGained', 'BufEnter', 'CursorHold', 'CursorHoldI'}, {
  pattern = '*',
  command = "if mode() !~ 'v(c|r.?|!|t)' && getcmdwintype() == '' | checktime | endif",
})

-- Notification after file change
-- https://vi.stackexchange.com/questions/13091/autocmd-event-for-autoread
vim.api.nvim_create_autocmd({'FileChangedShellPost'}, {
  pattern = '*',
  command = "echohl WarningMsg | echo 'File changed on disk. Buffer reloaded.' | echohl None",
})

Answered By: Christopher Poile
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.