Как мне заставить Вима вести себя как «tail -f»?


36

Я хотел бы знать, есть ли способ заставить Vim вести себя как tail -f.
Даже самый лучший плагин Vim, который я нашел до сих пор, не делает то, что я ожидаю.

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

Как это сделать?
(Я не хочу перезагружать весь файл, поскольку некоторые файлы журнала очень большие. Лучше всего загружать только последние строки, как это tail -fделает.)


2
Почему это должно быть внутри vim? Что не так с tail -f?
Свен

1
Потому что мне нужна сила vim, когда я читаю файлы журналов. Например, возможность поиска по шаблону, и особенно нравится выделение синтаксиса. Я сделал собственную подсветку синтаксиса для некоторых файлов журналов (bind, apache и т. Д.).

Вас может заинтересовать autoread и FileChangedShell >: help autoread>: help FileChangedShell
gsi-frank

2
Только для поиска, вы могли бы сделать less +Fвместо tail -f. Не дает вам подсветку синтаксиса.
Деннис Каарсемакер

Ответы:


28

Вы не можете заставить vimсебя вести себя как tail -f. Вы можете заставить lessсебя вести себя как комбинация vimи tail -fхотя.

Вперед навсегда (следовать) режим

lessимеет прямой режим навсегда, в который вы можете войти, нажав Fили передав +Fему аргумент.

$ less +F

В этом режиме lessведет себя как tail -fв том, что он не прекращает чтение, когда достигает конца файла. Он постоянно обновляется новыми данными из файла. Для выхода из этого режима нажмите Ctrlc.

Подсветка синтаксиса

lessподдерживает автоматическую фильтрацию данных, которые он читает. Существует программа с именем source-highlight, которая может выполнять базовую подсветку исходного кода. Это идет со сценарием, который хорошо работает с less. Чтобы использовать его, просто установите LESSOPENпеременную среды соответствующим образом.

 export LESSOPEN="| /path/to/src-hilite-lesspipe.sh %s"

Вы также должны указать lessпередать необработанные escape-последовательности терминала (они сообщают вашему терминалу, как окрашивать текст), передав ему -Rфлаг. Вы можете сказать, lessчто ему всегда передают -Rфлаг, установив LESSпеременную среды.

 export LESS=' -R '

Когда lessне достаточно

Несмотря на то, что у lessнего есть vi-подобные сочетания клавиш, это не то же самое, что Vim. Иногда он кажется чужим, и в нем отсутствуют важные функции, такие как интеграция ctags и возможность редактирования текста.

Вы можете сделать lessвызов Vim (при условии EDITOR=vim) файла, который он просматривает в данный момент, нажав v. lessдаже поместит курсор в правильном месте в Vim. Когда вы выйдете из Vim, вы снова окажетесь на less. Если вы внесли какие-либо изменения в файл во время работы в Vim, они будут отражены в less.


5
vim --servername TAIL_VIM /tmp/somefile

Теперь в другой оболочке (например, bash) вы можете сделать:

while true
do
    inotifywait --event modify /tmp/somefile \
    && vim --servername TAIL_VIM --remote-send '<C-\><C-N>:edit!<CR>G';
done

Когда <C -> <CN> заставляет vim перейти в обычный режим, "edit!" говорит vim перезагрузить текущий файл (CR имитирует нажатие клавиши ввода), и G переходит в конец файла. Удаление (G) облегчает вставку файла во время ввода.


Я вижу параметр "--servername" в человеке, однако я получил следующее сообщение об ошибке:VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Feb 10 2013 02:28:47) Option inconnue: "--servername=toto" Plus d'info avec: "vim -h"
Fox

если вы делаете vim --version, вы видите + clientserver (не -clientserver, с переносом)? Если нет, то многие люди компилируют vim из исходного кода, используя ./configure --with-features = огромный
crutux

Да, есть + клиентсервер. У меня есть версия Ubuntu.
Фокс

1

Я нашел ответ благодаря комментарию Эвана Тейтельмана . Мое решение основано на /usr/share/vim/vimcurrent/macros/less.vim .

Я сделал свою собственную функцию, но она могла бы быть значительно улучшена.

function! Tailf()
    e
    normal G
    redraw

    sleep 1
    call Tailf()
endfunction

И просто нажмите CTRL + C, чтобы выйти из Tailf.

Чтобы открыть файл журнала в режиме Tailf: view -M "+call Tailf()" /path/to/logfile.log

Что мне не нравится, так это sleepвызов, который не позволяет делать что-либо в vim во время автообновления. Лучше всего, если буфер будет автономным и обновляется, даже если я нахожусь в другом разделенном окне. Во всяком случае, это хорошее начало. :)


2
Похоже, что он также перечитывает весь файл, а это не то, что вы хотели, не так ли?
Бернхард

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

Да, это правда, он перезагружает весь файл, так что это должно быть значительно улучшено. Когда я говорю, что хочу этого, я больше говорю о результате (то, что вы видите на экране: vim, который обновляет ваш файл в одиночку и остается в последней строке). К сожалению, у меня недостаточно знаний о vim, чтобы создать хороший плагин ...
Fox

@EvanTeitelman Хорошо, теперь я вижу, как использовать inotifywait. Я могу знать, когда файл меняется. Но как узнать, был ли он добавлен (не полностью изменен), и как узнать, сколько новых строк было добавлено?
Фокс

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

1

Не рекурсивный метод для того же:

cmap tailf<CR> call Tailf()<CR>
         function! Tailf()
    "Press C-c to stop tailing
        while 1
            e                                  
            normal G
            redraw
            sleep 1
        endwhile
    endfunction

1

Мне нравится это коротко и без большого взлома. Вы можете запускать этот oneliner из ex (с vim) при необходимости (или помещать каждую команду в vimrc, когда открываются log-файлы).

:set autoread | au CursorHold * checktime | call feedkeys("lh")

(если вы хотите перейти (почти) к концу файла, просто используйте «G» вместо «lh» с кнопками)

Объяснение:

  • autoread: читает файл при изменении извне (но он не работает сам по себе, нет внутреннего таймера или чего-то в этом роде. Он будет читать файл только тогда, когда vim выполняет действие, как команда в ex :!
  • CursorHold * checktime: когда курсор не перемещается пользователем в течение времени, указанного в updatetime (который по умолчанию составляет 4000 миллисекунд) checktime, выполняется проверка изменений вне файла
  • call feedkeys("lh"): курсор перемещается один раз, вправо и назад влево. и тогда ничего не происходит (... что означает, что CursorHoldсрабатывает, что означает, что у нас есть цикл )

Чтобы остановить прокрутку при использовании call feedkeys("G") , выполните:set noautoread - теперь vim скажет, что файл был изменен, и спросит, хотите ли вы прочитать изменения или нет)

Мне нравится идея просматривать файлы журналов в vim (вместо tail -f), например, когда вы работаете в сеансе ssh без screen / tmux. Кроме того, вы можете при необходимости скопировать напрямую из файла журнала, или сохранить результаты напрямую или ... все, что вы можете сделать с помощью vim :)

* из этого ответа (ссылка на ответ от PhanHaiQuang и комментарий от flukus )


0

Редактировать: я прошу прощения, полностью обошел стороной, что вы уже пробовали это.

Вы можете попробовать использовать плагин Tail Bundle , я думаю, он должен делать то, что вы ищете.

Для установки откройте tail-3.0.vba с помощью vim и выполните:

:so %

Перезапустите, и вы сможете подключить файл из vim следующим образом:

:Tail /path/to/file

0

ТОЛЬКО для VIM 8.0+ были введены таймеры, так что вы можете использовать таймер для имитации функции хвоста, это довольно эффективно работает по моему опыту.

Я назначил клавишу F6, чтобы включить хвост, и клавишу F7, чтобы отключить хвост, вы можете настроить их в командах ниже, также см. Мой раздел ниже для СЛОВ ПРЕДОСТЕРЕЖЕНИЯ.

Запустите следующее

exe ":function! Tail(timer) \n :exe 'normal :e!\<ENTER>G' \n endfunction"
map <F6> :exe timer_start(2000, 'Tail', {'repeat':-1})<CR> 
map <F7> :exe timer_stopall()<CR>

Вы также можете сделать вышеуказанные команды частью vimrc, чтобы они всегда были у вас.

Несколько слов предостережения:

  • Я предполагаю, что у вас нет других таймеров, поэтому timer_stopall () фактически эффективно остановит все таймеры. Вы можете изменить это немного дальше, чтобы получить идентификатор во время timer_start, а затем удерживать его и т. Д., Но мне это показалось немного трудным, и я бы предположил, что большинство людей не будут использовать таймеры.
  • в то время как он находится в режиме хвоста, я настоятельно рекомендую вам не пытаться запускать какие-либо команды, это обычно приводит к сбою экземпляров vim, поэтому ПОЖАЛУЙСТА ОТКЛЮЧАЙТЕ ХВОСТ (F7), прежде чем вы решите вернуться в режим редактирования, это ТОЛЬКО СТРОГО ДЛЯ ПРОСМОТРА ЛОГОВ.

-1

В Vim выполните:

!tail -f 

Это приостановит Vim, в то время как разветвленный дочерний элемент выполняется tail -fв текущем буфере. Нажатие Ctrl-Cвозвращает вас обратно в буфер в Vim.


1
Это не vim, а просто tailделает работу. Vim портативный. Это не.
олигофрен
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.