Вопрос или проблема
Предполагая, что файл не имеет несохраненных изменений в буфере Vim, я хотел бы, чтобы он автоматически перезагружался, если файл изменяется на диске. Наиболее частый случай использования этого – когда я обновляю рабочую копию, в которой находится файл.
Как я могу этого добиться?
В вашем ~/.vimrc
:
set autoread
Это то, что сработало для меня.
set autoread
au CursorHold * checktime
Первой строки было недостаточно. Вы можете добавить это в ваш .vimrc
.
из этого ответа (ссылаясь на ответ PhanHaiQuang и комментарий от @flukus)
Можно выполнить эту однострочную команду в ex (внутри vim), когда нужно (или поместить каждую команду в vimrc, когда открыты лог-файлы).
:set autoread | au CursorHold * checktime | call feedkeys("lh")
Объяснение:
– autoread: читает файл, когда он изменяется извне (но сам по себе он не работает, нет внутреннего таймера или чего-то подобного. Он будет читать файл только тогда, когда vim выполняет действие, например, команду в ex :!
– CursorHold * checktime: когда курсор не перемещается пользователем в течение времени, указанного в ‘updatetime’ (по умолчанию 4000 миллисекунд), выполняется checktime, который проверяет изменения извне файла
– call feedkeys(“lh”): курсор перемещается один раз, вправо и обратно влево. и затем ничего не происходит (… это означает, что срабатывает CursorHold, что означает, что у нас есть цепная реакция)
Autoread не работает корректно. Следующее работает для меня:
Сначала необходимо установить скрипт из здесь.
Я получил лучшие результаты, вызывая функцию настройки напрямую, вот так:
let autoreadargs={'autoread':1}
execute WatchForChanges("*",autoreadargs)
Причина этого в том, что я хочу запустить настройку ipython/screen/vim.
Вы можете легко преобразовать это в улучшенную версию просмотра.
скрипт процесса..
mkdir -p ~/bin
cat <<`OUT` > ~/bin/vimviewer
#!/usr/bin/env sh
exec vim -n --cmd "source /home/bryan/.vim/.vimrc.watchforchanges | let autoreadargs={'autoread':1} | execute WatchForChanges('*',autoreadargs)" $@
`OUT`
chmod 755 ~/bin/vimviewer
vimview test.txt
плагин vim-autoread до сих пор работал для меня:
vim-autoread
Автоматически заставляет vim перезагружать файлы, которые были записаны на
диск, но не изменялись в буфере с момента последней записи из vim.
Это позволяет редактировать файл, открытый в vim, с помощью другого приложения
и сохранять его. После возврата в vim, пока вы не изменили файл с момента последнего изменения, файл будет автоматически обновлен, чтобы отразить изменения, внесенные на диске, так, как будто вы нажали :e
вручную.
Существуют некоторые плагины, перечисленные здесь, которые могут работать в зависимости от вашей версии Vim.
Другой подход заключается в том, чтобы периодически отправлять команду checktime
в vim из внешнего процесса. Вот скрипт ShellJS для этого (требует shelljs-plugin-sleep
, NeoVim и nvr
):
while (true) {
sleep(15);
var servernames = exec('nvr --serverlist').trim().split('\n');
if (!servernames.length || !servernames[0]) {
continue;
}
servernames.forEach(
(sn) => exec(`nvr -c "checktime" --servername ${sn}`) );
}
Используя это с алиасом, который я помещаю в /etc/profile для использования всеми пользователями:
alias viml="vim $\"+:set autoread | au CursorHold * checktime | call feedkeys('lh')\" "
Теперь вы можете вызвать viml, который будет перезагружать файл при каждом изменении (с небольшой задержкой). Это удержит вас на текущей строке курсора. Нажмите Shift+G, чтобы перейти к концу файла.
sudo viml /var/log/mysql/mysql.log
Я использую :set autoread
, не в .vimrc, а в командной строке для конкретного файла, например:
vim filename +'set autoread'
Работает хорошо. Единственный недостаток в том, что мне нужно сфокусироваться на vim и нажать G, чтобы отобразить последние добавления в файл.
Ответ или решение
Чтобы автоматически перезагружать файл в Vim при изменении на диске, вы можете использовать несколько подходов.
Шаг 1: Настройка autoread
В вашем файле конфигурации ~/.vimrc
добавьте следующие строки:
set autoread " Включает автоматическое чтение файла при его изменении
au CursorHold * checktime " Проверяет состояние файла, если курсор не перемещается
Объяснение команд
-
set autoread
: Эта команда увеличивает вероятность того, что Vim будет загружать файл, если он был изменен извне. Однако по умолчанию она не будет работать, если в буфере есть несохраненные изменения. -
*`au CursorHold checktime
**: Эта команда вызывает команду
checktime, когда курсор находится без движения (по умолчанию настройка
updatetime` равна 4000 миллисекунд). Эта команда проверяет изменения во внешних файлах.
Шаг 2: Обходные методы
Если autoread
не работает должным образом, вы можете использовать плагины или дополнительные скрипты для улучшения функциональности.
Использование плагина vim-autoread
Рекомендую установить плагин vim-autoread
, который автоматически перезагружает файлы, измененные на диске, без необходимости вручную вызывать :e
:
- Установите плагин с помощью вашего менеджера плагинов.
- Добавьте в
~/.vimrc
:
Plug 'djoshea/vim-autoread'
Этот плагин позволит вам избегать проблем с автозагрузкой, когда файл изменяется в другом приложении.
Альтернативное решение с nvr
Вы также можете запустить скрипт, который будет периодически отправлять команду checktime
в Vim. Вот пример на JavaScript с использованием ShellJS:
while (true) {
sleep(15);
var servernames = exec('nvr --serverlist').trim().split('\n');
if (!servernames.length || !servernames[0]) {
continue;
}
servernames.forEach(
(sn) => exec(`nvr -c "checktime" --servername ${sn}`) );
}
Шаг 3: Альтернативные варианты запуска Vim
Вы можете создать алиас для запуска Vim с нужными настройками:
alias viml="vim +'set autoread | au CursorHold * checktime | call feedkeys('lh')'"
После этого можно запускать Vim с помощью viml
, и он будет автоматически проверять изменения в файле.
Заключение
Следуя указанным шагам, вы можете настроить Vim для автоматической перезагрузки файлов при их изменении на диске. Это значительно упростит вашу работу, особенно если вы редактируете файлы в нескольких приложениях одновременно.