- Вопрос или проблема
- Кратко
- Вручную
- Автоматически
- Триггер при остановке курсора
- Триггер при изменении буфера или фокусе терминала
- Уловка фокуса окна терминала внутри простого vim
- Итог
- Ответ или решение
- 1. Ручное обновление
- 2. Автоматическое обновление
- Дополнительные команды
- 3. Настройка автокоманд
- 4. Уведомления о изменения
- 5. Использование терминала
- Заключение
Вопрос или проблема
У меня есть конфигурационный файл, который я держу открытым в vim, но иногда он изменяется на диске, и эти изменения не отображаются в терминале. Могу ли я обновить содержимое на экране, не закрывая и не открывая файл заново? Если да, то как?
Вы можете использовать команду :edit
, не указывая имя файла, чтобы перезагрузить текущий файл. Если вы внесли изменения в файл, вы можете использовать :edit!
, чтобы принудительно перезагрузить текущий файл (вы потеряете свои изменения).
Команду :edit
можно сократить до :e
. Принудительную загрузку можно выполнить, используя :e!
Кроме того, вы можете добавить в свой ~/.vimrc
:set autoread
чтобы Vim автоматически обновлял любые файлы, которые не были изменены в Vim. Также смотрите :checktime
.
Кратко
Перейдите к заголовку Wrap-up
для строк vimrc
, которые нужно добавить, чтобы сделать вашу жизнь лучше.
Вручную
Запустите :checktime
Проверьте, были ли изменены какие-либо буферы вне Vim. Это проверяет и предупреждает вас, если у вас окажется две версии файла.
Автоматически
Чтобы автоматически загружать изменения, добавьте в свой vimrc
:
Когда файл был обнаружен как измененный вне 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, и помогут избежать несоответствий между версией файла на диске и его отображением в редакторе. Выберите подходящий способ, основываясь на ваших рабочих привычках и потребностях.