Мой вопрос похож на этот как отслеживать текстовый файл в реальном времени
но я хочу сделать это в vim. Я знаю, что я могу прочитать файл с открытым файлом, использующий tail -f sample.xml
, и когда в файл будет записан новый контент, он также напишет новый контент на мой экран. Могу ли я использовать vim для автоматического заполнения новых данных при обновлении файла?
Может ли vim контролировать изменения в реальном времени в файле
Ответ 1
Вы можете :set autoread
, чтобы vim читал файл при его изменении. Однако (в зависимости от вашей платформы) вы должны уделять ему внимание.
С помощью:
Когда файл обнаружен был изменен вне Vim, и он не было изменено внутри Vim, автоматически прочитайте его снова. Когда файл удален, это не сделал.
Ответ 2
Не знаю об автоматическом, но вы можете ввести:
:e!
чтобы перезагрузить файл
Ответ 3
Поместите в .vimrc
следующее:
" check one time after 4s of inactivity in normal mode set autoread au CursorHold * checktime
Ответ 4
Tail Bundle должен делать то, что вы хотите. Заметьте, я не использовал его сам.
Ответ 5
как @flukus сказал в комментарии к предыдущему ответу, вы можете call feedkeys["lh"]
(он перемещает курсор вправо и назад влево, что normaly doesn не вредите при просмотре файла журнала) jk
Итак, если вы объедините оставшуюся часть ответа , у вас есть oneliner, вы можете использовать ex (whithin vim) при необходимости:
:set autoread | au CursorHold * checktime | call feedkeys("lh")
(если вы хотите прыгать (почти) в конец файла, просто используйте "G" вместо "lh" с ключами-ключами)
Объяснение:
- autoread: читает файл при изменении извне (но он не работает сам по себе, нет внутреннего таймера или что-то в этом роде. Он будет читать только файл, когда vim выполняет действие, например команда в ex :!
- CursorHold * checktime: когда курсор не перемещается пользователем в течение времени, указанного в "updatetime" (который по умолчанию составляет 4000 миллисекунд), выполняется проверка времени, которое проверяет наличие изменений вне файла
- клавиши вызова ( "lh" ): курсор перемещается один раз, вправо и назад влево. и тогда ничего не происходит (... что означает, что CursorHold запускается, что означает, что мы имеем цикл)
Кроме того, вы можете :set syntax=logtalk
раскрасить журнал
Чтобы остановить прокрутку при использовании call feedkeys("G")
, выполните :set noautoread
- теперь vim скажет, что файл был изменен и спросили, хотите ли вы прочитать изменения или нет)
(Имеет ли это какие-либо побочные эффекты?)
Ответ 6
Вставьте это в свой .vimrc, и он должен работать как босс. (Взято из: http://vim.wikia.com/wiki/Have_Vim_check_automatically_if_the_file_has_changed_externally)
" Function to Watch for changes if buffer changed on disk
function! WatchForChanges(bufname, ...)
" Figure out which options are in effect
if a:bufname == '*'
let id = 'WatchForChanges'.'AnyBuffer'
" If you try to do checktime *, you'll get E93: More than one match for * is given
let bufspec = ''
else
if bufnr(a:bufname) == -1
echoerr "Buffer " . a:bufname . " doesn't exist"
return
end
let id = 'WatchForChanges'.bufnr(a:bufname)
let bufspec = a:bufname
end
if len(a:000) == 0
let options = {}
else
if type(a:1) == type({})
let options = a:1
else
echoerr "Argument must be a Dict"
end
end
let autoread = has_key(options, 'autoread') ? options['autoread'] : 0
let toggle = has_key(options, 'toggle') ? options['toggle'] : 0
let disable = has_key(options, 'disable') ? options['disable'] : 0
let more_events = has_key(options, 'more_events') ? options['more_events'] : 1
let while_in_this_buffer_only = has_key(options, 'while_in_this_buffer_only') ? options['while_in_this_buffer_only'] : 0
if while_in_this_buffer_only
let event_bufspec = a:bufname
else
let event_bufspec = '*'
end
let reg_saved = @"
"let autoread_saved = &autoread
let msg = "\n"
" Check to see if the autocommand already exists
redir @"
silent! exec 'au '.id
redir END
let l:defined = (@" !~ 'E216: No such group or event:')
" If not yet defined...
if !l:defined
if l:autoread
let msg = msg . 'Autoread enabled - '
if a:bufname == '*'
set autoread
else
setlocal autoread
end
end
silent! exec 'augroup '.id
if a:bufname != '*'
"exec "au BufDelete ".a:bufname . " :silent! au! ".id . " | silent! augroup! ".id
"exec "au BufDelete ".a:bufname . " :echomsg 'Removing autocommands for ".id."' | au! ".id . " | augroup! ".id
exec "au BufDelete ".a:bufname . " execute 'au! ".id."' | execute 'augroup! ".id."'"
end
exec "au BufEnter ".event_bufspec . " :checktime ".bufspec
exec "au CursorHold ".event_bufspec . " :checktime ".bufspec
exec "au CursorHoldI ".event_bufspec . " :checktime ".bufspec
" The following events might slow things down so we provide a way to disable them...
" vim docs warn:
" Careful: Don't do anything that the user does
" not expect or that is slow.
if more_events
exec "au CursorMoved ".event_bufspec . " :checktime ".bufspec
exec "au CursorMovedI ".event_bufspec . " :checktime ".bufspec
end
augroup END
let msg = msg . 'Now watching ' . bufspec . ' for external updates...'
end
" If they want to disable it, or it is defined and they want to toggle it,
if l:disable || (l:toggle && l:defined)
if l:autoread
let msg = msg . 'Autoread disabled - '
if a:bufname == '*'
set noautoread
else
setlocal noautoread
end
end
" Using an autogroup allows us to remove it easily with the following
" command. If we do not use an autogroup, we cannot remove this
" single :checktime command
" augroup! checkforupdates
silent! exec 'au! '.id
silent! exec 'augroup! '.id
let msg = msg . 'No longer watching ' . bufspec . ' for external updates.'
elseif l:defined
let msg = msg . 'Already watching ' . bufspec . ' for external updates'
end
echo msg
let @"=reg_saved
endfunction
let autoreadargs={'autoread':1}
execute WatchForChanges("*",autoreadargs)
Ответ 7
Существует также плагин:
https://github.com/djoshea/vim-autoread
Это был единственный способ сделать эту работу на OSX.
Ответ 8
VIM предупредит вас, когда файл обновлен, чтобы вы не перезаписывали изменения, которые были сделаны с момента его открытия. В этот момент вам будет предложено перезагрузить файл.
Ответ 9
Решение для пуленепробиваемых (кросс-OS):
:autocmd WinEnter <buffer> :view
Это не в реальном времени, но обновляет буфер каждый раз, когда вы входите.
Ответ 10
Если unix + neovim
:term tail -f <filename>
Очевидно, что это не сработает для всех, но как я это делаю.