刷新在vi(m)中打开的文件的更改内容


362

我有一个配置文件,该文件在vim中保持打开状态,但有时会在磁盘上更改,而这些更改不会反映在终端上。是否可以在不关闭并重新打开文件的情况下刷新屏幕上的内容?如果是这样,怎么办?



总结:到目前为止,所有答案都是“投票”而不是“推”式的。也就是说,这些答案不是像其他软件的类似功能那样接收外部文件更改事件,而是依靠vim主动轮询文件更改,无论是手动操作还是由用户操作或计时器触发。最终结果是您不会立即看到更改刷新在屏幕上。
Penghe Geng

Answers:


464

您可以在:edit不指定文件名的情况下使用该命令来重新加载当前文件。如果对文件进行了修改,则可以:edit!用来强制重新加载当前文件(您将丢失所做 的修改)。

该命令:edit可以用缩写:e。因此,可以通过以下方式进行强制编辑:e!


2
“!” 在绊倒我,但现在很明显。
twan163

107
注意:通常缩写为:e!
斯特凡Chazelas

31
@StephaneChazelas:是的,这是正确的:) @ twan163:相反的:edit,并:edit!可以使用:e:e!分别。
2014年

11
丢失修改,是和否。至关重要的是,您仍然u可以执行:e!
Gerrit

5
另外,如果要重新加载所有缓冲区,请运行::bufdo e
pkout

193

除了使用手动刷新文件外:edit,您还可以将其放入~/.vimrc

:set autoread

使Vim自动刷新Vim尚未编辑的所有文件。另请参阅:checktime


2
买方要当心-如果您正在使用新代码,并且git pull要注意,您可能会无意间在屏幕上丢失未保存的更改。
azatar

5
@toszter不,Vim只会刷新未更改的缓冲区。如果发生更改,仍然会有一个查询:保留还是加载?
Ingo Karkat

10
NB 自动读取不能完全自动工作。您必须使用gvim或运行外部命令。
Sparhawk

3
那些在tmux内部使用vim的人可以通过使用github.com/tmux-plugins/vim-tmux-focus-events获得焦点事件。否则,除非您以某种方式致电,否则自动读取不会对终端产生帮助:checktime
Karl Bartel

3
autoread可以在光标停止移动X秒钟后自动触发,请参见此答案
汤姆·黑尔

57

TL; DR

跳到Wrap-up标题vimrc以增加内容,以使您的生活更美好。

手动地

:checktime

检查是否在Vim之外更改了任何缓冲区。这将检查并警告您是否最终将使用文件的两个版本。

自动地

要自动加载更改,请添加vimrc

set autoread

当检测到文件在Vim外部已被更改并且在Vim内部尚未被更改时,请自动重新读取。删除文件后,不会完成此操作。

这个答案增加了一个警告:

除非您执行诸如运行外部命令(如!ls!sh等)之类的操作,否则自动读取不会重新加载文件

请继续阅读以获取解决方案。

光标停止移动时触发

添加到您的vimrc

au CursorHold,CursorHoldI * checktime

默认情况下,CursorHold在光标保持静止4秒钟后触发,并且可以通过updatetime进行配置。

触发缓冲区更改或终端焦点

vim 内部更改缓冲区时,向您添加以下内容以vimrc触发:autoread

au FocusGained,BufEnter * :checktime

在普通vim中捕获终端窗口焦点

FocusGained在普通vim中工作(请参见上文),请在终端仿真器(Xterm,tmux等)中安装插件: vim-tmux-focus-events

在tmux版本> 1.9上,您需要添加.tmux.conf

set -g focus-events on

包起来

autoread触发器触发时也可能发出通知

这是我vimrc实现上述所有内容的代码:

" 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() != 'c' | 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

感谢ErichBSchulz用指示我正确的方向au CursorHold


2
优秀的帖子!感觉其中之一应该是默认行为
JonnyRaa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.