обновить измененное содержимое файла, открытого в vi (m)

362

У меня есть config-файл, который я сохраняю открытым в vim, но иногда он изменяется на диске, и эти изменения не отражаются на терминале. Могу ли я обновить содержимое на экране без закрытия и повторного открытия файла? Если так, то как?

twan163
источник
Подводя итог: все ответы до сих пор имеют «опрос» вместо стиля «толчок». То есть вместо получения события внешнего изменения файла, как это было сделано с помощью аналогичных функций другого программного обеспечения, эти ответы основаны на том, что vim активно опрашивает изменение файла, либо вручную, либо запускается действием пользователя или таймером. В результате вы не увидите изменения, обновленные на экране мгновенно.
Пенге Гэн

Ответы:

464

Вы можете использовать :editкоманду без указания имени файла, чтобы перезагрузить текущий файл. Если вы внесли изменения в файл, вы можете использовать :edit!для принудительной перезагрузки текущего файла (вы потеряете ваши изменения).

Команда :editможет быть сокращена до :e. Таким образом, принудительное редактирование может быть выполнено:e!

Thushi
источник
2
"!" подножка меня, но теперь все ясно.
twan163
107
Примечание: это обычно сокращенно до :e!.
Стефан Шазелас
31
@StephaneChazelas: Да, это правильно :) @ twan163: Вместо, :editи :edit!вы можете использовать :eи :e!соответственно.
Thushi
11
Потерять модификации, да и нет. Важно, что вы все еще можете uотменить :e!.
Gerrit
5
Кроме того, если вы хотите перезагрузить все свои буферы, запустите::bufdo e
pkout
193

В дополнение к обновлению файла вручную :edit, вы можете поместить в свой~/.vimrc

:set autoread

чтобы Vim автоматически обновлял любые файлы, которые не были отредактированы Vim. Также см :checktime.

Инго Каркат
источник
2
Покупатель остерегается - если вы работаете над новым кодом и git pullпомните, что несохраненные изменения могут быть потеряны на экране довольно непреднамеренно.
Азатар
5
@toszter Нет, Vim будет обновлять только неизмененные буферы. В случае изменений все равно останется запрос: сохранить или загрузить?
Инго Каркат
10
NB autoread не работает автоматически. Вы должны либо использовать gvim, либо запустить внешние команды.
Ястреб
3
Те, кто использует vim внутри tmux, могут получать события фокуса с помощью github.com/tmux-plugins/vim-tmux-focus-events . В противном случае автоматическое чтение не поможет в терминале, если вы не позвоните:checktime
Карл Бартел
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 секунд, и настраивается через время обновления .

Триггер при смене буфера или фокусе терминала

Добавьте следующее к вашему, vimrcчтобы срабатывать autoreadпри изменении буферов внутри vim:

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