Может ли vim контролировать изменения в реальном времени в файле

Мой вопрос похож на этот как отслеживать текстовый файл в реальном времени но я хочу сделать это в vim. Я знаю, что я могу прочитать файл с открытым файлом, использующий tail -f sample.xml, и когда в файл будет записан новый контент, он также напишет новый контент на мой экран. Могу ли я использовать 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>

Очевидно, что это не сработает для всех, но как я это делаю.