Como faço para o Vim se comportar como "tail -f"?


36

Gostaria de saber se existe uma maneira de fazer com que o Vim se comporte tail -f.
Até o melhor plugin Vim que encontrei até agora não faz o que eu esperava.

Eu realmente quero ver a atualização do arquivo em tempo real . Mesmo longe do teclado, quero que o Vim recarregue constantemente o buffer e pule para a última linha.

Como fazer isso?
(Não quero recarregar o arquivo inteiro, pois alguns arquivos de log são muito grandes. O melhor é carregar apenas as últimas linhas, como tail -ffaz.)


2
Por que deve estar dentro vim? O que há de errado tail -f?
Sven

11
Porque eu quero o poder do vim quando leio arquivos de log. É como poder procurar um padrão e aproveitar o destaque da sintaxe. Fiz minha própria sintaxe destacando alguns arquivos de log (bind, apache, etc.).

Você poderia estar interessado em Autoread e FileChangedShell >: ajuda Autoread>: ajuda FileChangedShell
GSI-franca

2
Apenas para a pesquisa, você poderia fazer em less +Fvez de tail -f. Porém, não fornece a sintaxe destacada.
Dennis Kaarsemaker

Respostas:


28

Você não pode fazer vimcomo se comportar tail -f. Você pode se lesscomportar como uma combinação de vime no tail -fentanto.

Avançar para sempre (seguir)

lesspossui um modo encaminhar para sempre que você pode acessar pressionando Fou passando +Fcomo argumento.

$ less +F

Nesse modo, lesscomporta-se como tail -fse não parasse de ler quando chegasse ao final de um arquivo. Ele atualiza constantemente com novos dados do arquivo. Para sair deste modo, pressione Ctrlc.

Realce de sintaxe

lesssuporta filtragem automática dos dados que lê. Existe um programa chamado source-realce que pode executar o destaque básico do código-fonte. Ele vem com um script que funciona bem com less. Para usá-lo, basta definir a LESSOPENvariável ambiental adequadamente.

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

Você também precisa informar lesspara passar as seqüências de escape brutas do terminal (elas informam ao terminal como colorir o texto) passando a -Rbandeira. Você pode dizer lesspara fingir que está sempre passando a -Rbandeira definindo a LESSvariável ambiental.

 export LESS=' -R '

Quando lessnão é suficiente

Embora lesstenha atalhos de teclado parecidos com vi, não é o mesmo que Vim. Às vezes, parece estranho e carece de recursos importantes, como a integração de ctags e a capacidade de editar texto.

Você pode fazer a lesschamada Vim (supondo EDITOR=vim) no arquivo que está visualizando atualmente pressionando v. lessaté colocará o cursor no local correto no Vim. Ao sair do Vim, você voltará a less. Se você fez alguma alteração no arquivo enquanto estava no Vim, elas serão refletidas less.


5
vim --servername TAIL_VIM /tmp/somefile

Agora, em outro shell (como o bash), você pode:

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

Onde o <C -> <CN> força o vim a entrar no modo normal, "edite!" diz ao vim para recarregar o arquivo atual (o CR simula pressionando enter) e G vai para a parte inferior do arquivo. A remoção de (G) facilita a inseptação do arquivo enquanto a entrada é recebida.


Eu vejo o parâmetro "--servername" no homem, no entanto, recebi a seguinte mensagem de erro: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

se você vim --version você vê + clientserver (não -clientserver, com um hypen)? Se não, muitas pessoas compilação vim de origem utilizando ./configure --with-recursos = enorme
crutux

Sim, existe + clientserver. Eu tenho a versão do Ubuntu.
Fox

1

Encontrei a resposta graças ao comentário de Evan Teitelman . Minha solução é inspirada em /usr/share/vim/vimcurrent/macros/less.vim .

Eu fiz minha própria função, mas poderia ser melhorada muito.

function! Tailf()
    e
    normal G
    redraw

    sleep 1
    call Tailf()
endfunction

E apenas pressione CTRL + C para sair do Tailf.

Para abrir um arquivo de log no modo Tailf: view -M "+call Tailf()" /path/to/logfile.log

O que não gosto é a sleepchamada, que não permite fazer nada no vim durante a atualização automática. O melhor seria se o buffer fosse autônomo e fosse atualizado mesmo se eu estivesse em outra janela dividida. Enfim, é um bom começo. :)


2
Parece que ele também relê o arquivo inteiro, o que não é o que você queria, certo?
Bernhard

Isso recarrega o arquivo inteiro. Provavelmente não seria muito difícil criar um plug-in baseado no inotifywait e :readisso espera até que um arquivo seja modificado e, se tiver sido anexado, lê as linhas na parte inferior do arquivo.

Sim, é verdade, ele recarrega o arquivo inteiro, então isso precisa ser muito melhorado. Quando digo que quero isso, estou mais falando sobre o resultado (o que você vê na tela: um vim que atualiza seu arquivo sozinho e permanece na última linha). Infelizmente eu não tenho conhecimento vim suficiente para fazer um plugin legal ...
Fox

@EvanTeitelman OK, agora vejo como usar o inotifywait. Eu posso saber sempre que o arquivo for alterado. Mas como saber se foi anexado (não completamente modificado) e como saber quantas novas linhas foram anexadas?
Fox

Leia o número de linhas no arquivo sempre que o arquivo for alterado. Se o número de linhas aumentar, leia as alterações.

1

Um método não recursivo para o mesmo:

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

Eu gosto curto e sem muita invasão. Você pode executar este oneliner a partir de ex (dentro do vim) quando necessário (ou colocar cada comando no vimrc, para quando os arquivos de log forem abertos.)

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

(se você quiser pular (quase) para o final do arquivo, use "G" em vez de "lh" com as teclas de feed)

Explicação:

  • autoread: lê o arquivo quando alterado do lado de fora (mas não funciona por si só, não há cronômetro interno ou algo assim. Ele só lerá o arquivo quando o vim executar uma ação, como um comando em ex :!
  • CursorHold * checktime: quando o cursor não é movido pelo usuário pelo tempo especificado em updatetime(que é de 4000 milissegundos por padrão)checktime é executado, que verifica alterações fora do arquivo
  • call feedkeys("lh"): o cursor é movido uma vez, direita e volta à esquerda. e então nada acontece (... o que significa que CursorHoldé acionado, o que significa que temos um loop )

Para parar a rolagem ao usar call feedkeys("G"), execute :set noautoread- agora o vim dirá que o arquivo foi alterado e pergunta se alguém deseja ler as alterações)

Eu gosto da idéia de assistir arquivos de log no vim (em vez de tail -f), por exemplo, quando você está trabalhando em uma sessão ssh sem screen / tmux. Além disso, você pode copiar diretamente do arquivo de log, se necessário, ou salvar a saída diretamente ou ... o que você puder fazer com o vim :)

* desta resposta (referindo-se a uma resposta de PhanHaiQuang e a um comentário de flukus )


0

Edit: Peço desculpas, completamente ignorado que você já tentou isso.

Você pode tentar usar o plugin Tail Bundle , acho que ele deve fazer o que você está procurando.

Para instalar, abra o tail-3.0.vba com o vim e execute:

:so %

Reinicie e você deve conseguir inicializar um arquivo no vim da seguinte forma:

:Tail /path/to/file

0

SOMENTE No VIM 8.0+, eles introduziram temporizadores, para que você pudesse usar um temporizador para simular a função de cauda, ​​isso funciona de maneira bastante eficaz na minha experiência.

Mapeei a tecla F6 para ativar a cauda e F7 para desativar a cauda; você pode personalizá-los nos comandos abaixo; também veja minha seção abaixo para PALAVRAS DE CUIDADO.

Execute o seguinte

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>

Você também pode fazer com que os comandos acima façam parte do vimrc, para sempre tê-los.

Algumas palavras de cautela:

  • Suponho que você não tenha outros cronômetros, portanto timer_stopall () na verdade interromperá efetivamente todos os cronômetros. Você pode modificar isso um pouco mais para obter o ID durante o timer_start e, em seguida, mantê-lo, etc.
  • Enquanto estiver no modo cauda, ​​eu sugiro que você não tente executar nenhum comando; ele geralmente trava as instâncias do vim; portanto, desative o TAIL (F7) antes de decidir voltar ao modo de edição, isso é apenas estritamente PARA VISUALIZAR LOGS.

-1

No Vim, execute:

!tail -f 

Isso suspenderá o Vim enquanto o filho bifurcado é executado tail -fno buffer atual. Pressionando Ctrl-Cretorna você de volta ao buffer no Vim.


11
Isso não é vim, mas é claro que está tailfazendo o trabalho. O Vim é portátil. Isso não é.
oligofren
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.