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

Вопрос или проблема

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

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

Команду :edit можно сократить до :e. Принудительную загрузку можно выполнить, используя :e!

Кроме того, вы можете добавить в свой ~/.vimrc

:set autoread

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

Кратко

Перейдите к заголовку Wrap-up для строк vimrc, которые нужно добавить, чтобы сделать вашу жизнь лучше.

Вручную

Запустите :checktime

Проверьте, были ли изменены какие-либо буферы вне Vim. Это проверяет и предупреждает вас, если у вас окажется две версии файла.

Автоматически

Чтобы автоматически загружать изменения, добавьте в свой vimrc:

set autoread

Когда файл был обнаружен как измененный вне Vim и он не был изменен внутри Vim, автоматически прочитайте его снова. Когда файл был удален, это не выполняется.

Этот ответ добавляет оговорку:

Autoread не перезагружает файл, если вы не сделаете что-то вроде запуска внешней команды (например, !ls или !sh и т.д.)

Читать дальше для решений.

Триггер при остановке курсора

Добавьте в свой vimrc:

au CursorHold,CursorHoldI * checktime

По умолчанию CursorHold срабатывает после того, как курсор остается неподвижным в течение 4 секунд, и это можно настроить через updatetime.

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

Добавьте следующее в свой 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, чтобы реализовать всё вышеперечисленное:

" Триггерить `autoread` когда файлы изменяются на диске
" 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

" Уведомление после изменения файла
" https://vi.stackexchange.com/questions/13091/autocmd-event-for-autoread
autocmd FileChangedShellPost *
  \ echohl WarningMsg | echo "Файл изменён на диске. Буфер перезагружен." | echohl None

Спасибо ErichBSchulz за направление в нужное русло с au CursorHold.

Спасибо этому ответу за решение проблемы с cmdwin.

Предполагая Linux, что работает для меня, так это отправка vim в фоновый режим с помощью ctrl+z, возврат его в фоновый режим с помощью fg и затем нажатие L в приглашении.

Будьте осторожны с несохранённой работой.

Ответ или решение

Когда вы работаете с файлом в редакторе Vim и изменения в этом файле происходят на диске, вы можете обновить содержимое файла на экране без необходимости его закрытия и повторного открытия. Вот несколько способов, как это сделать:

1. Ручное обновление

Чтобы вручную обновить текущий файл, выполните команду:

:edit

Эта команда перезагрузит содержимое файла. Если у вас есть несохраненные изменения и вы хотите принудительно перезагрузить файл, вы можете использовать:

:edit!

Учтите, что в этом случае все ваши несохраненные изменения будут потеряны.

Команду :edit также можно сократить до :e:

:e

А для принудительной перезагрузки:

:e!

2. Автоматическое обновление

Для автоматического обновления файла при его изменении вне Vim, вы можете добавить следующую строку в ваш файл конфигурации ~/.vimrc:

set autoread

Эта настройка позволяет Vim автоматически загружать файл заново, если он был изменен вне редактора.

Дополнительные команды

Для проверки, изменился ли файл на диске, вы можете использовать команду:

:checktime

Эта команда проверяет, были ли изменения во всех буферах и предупреждает, если файл был изменен.

3. Настройка автокоманд

Для более продвинутой автоматизации вы можете настроить автокоманды, которые будут выполнять проверки времени изменения при движении курсора или переключении между буферами. Для этого добавьте следующие строки в ваш ~/.vimrc:

augroup AutoRead
  autocmd!
  autocmd FocusGained,BufEnter,CursorHold,CursorHoldI * if mode() !~ '\v(c|r.?|!|t)' && getcmdwintype() == '' | checktime | endif
augroup END

Этот код будет автоматически вызывать checktime при получении фокуса, входе в буфер или при удерживании курсора.

4. Уведомления о изменения

Чтобы получать уведомления, когда файл изменяется, вы можете добавить следующую автокоманду:

autocmd FileChangedShellPost * echohl WarningMsg | echo "File изменился на диске. Буфер перезагружен." | echohl None

5. Использование терминала

Если вы работаете в терминале и хотите быстро обновить файл, вы можете приостановить Vim, нажав Ctrl + Z, затем вернуть его в foreground командой fg, и вы сможете обновить буфер с помощью :e или :edit.

Заключение

Эти методы позволят вам эффективно управлять изменениями файлов, открытых в Vim, и помогут избежать несоответствий между версией файла на диске и его отображением в редакторе. Выберите подходящий способ, основываясь на ваших рабочих привычках и потребностях.

Оцените материал
Добавить комментарий

Капча загружается...