¿Cómo hago que Vim se comporte como "tail -f"?


36

Me gustaría saber si hay una manera de hacer que Vim se comporte como tail -f.
Incluso el mejor complemento de Vim que he encontrado hasta ahora no hace lo que esperaba.

Realmente quiero ver la actualización del archivo en tiempo real . Incluso si estoy lejos del teclado, quiero que Vim vuelva a cargar constantemente el búfer y salte a la última línea.

¿Como hacer esto?
(No quiero volver a cargar todo el archivo, ya que algunos archivos de registro son muy grandes. Lo mejor es cargar solo las últimas líneas, como lo tail -fhace).


2
¿Por qué debe estar dentro vim? ¿Qué tiene de malo tail -f?
Sven

1
Porque quiero el poder de vim cuando leo archivos de registro. Como poder buscar patrones y disfrutar especialmente del resaltado de sintaxis. Hice mi propio resaltado de sintaxis para algunos archivos de registro (bind, apache, etc.).

Usted podría estar interesado en autoread y FileChangedShell >: help autoread>: help FileChangedShell
gsi-frank

2
Solo por la búsqueda, podría hacer en less +Flugar de tail -f. Sin embargo, no te da el resaltado de sintaxis.
Dennis Kaarsemaker

Respuestas:


28

No puedes hacer que se vimcomporte como tail -f. Puede hacer que se lesscomporte como una combinación de vimy tail -fsin embargo.

Modo de reenviar para siempre (seguir)

lesstiene un modo de reenvío para siempre al que puede ingresar presionando Fo pasando +Fa él como argumento.

$ less +F

En este modo, se lesscomporta como tail -fsi no dejara de leer cuando llega al final de un archivo. Se actualiza constantemente con nuevos datos del archivo. Para salir de este modo, presione Ctrlc.

Resaltado de sintaxis

lessadmite el filtrado automático de los datos que lee. Hay un programa llamado source-highlighting que puede realizar resaltado básico del código fuente. Viene con un script que funciona bien con less. Para usarlo, simplemente configure la LESSOPENvariable ambiental de manera adecuada.

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

También debe indicarle lessque pase secuencias de escape de terminal sin procesar (estas le indican a su terminal cómo colorear el texto) pasándole la -Rbandera. Puedes decir lessque finges que siempre se pasa la -Rbandera configurando la LESSvariable ambiental.

 export LESS=' -R '

Cuando lessno es suficiente

Aunque lesstiene combinaciones de teclas tipo vi, simplemente no es lo mismo que Vim. A veces se siente extraño y carece de características importantes, como la integración de ctags y la capacidad de editar texto.

Puede hacer una lessllamada a Vim (suponiendo EDITOR=vim) en el archivo que está viendo actualmente presionando v. lessincluso colocará el cursor en la ubicación correcta dentro de Vim. Cuando salgas de Vim, te encontrarás nuevamente en less. Si realizó algún cambio en el archivo mientras estaba en Vim, se reflejará en él less.


5
vim --servername TAIL_VIM /tmp/somefile

Ahora, en otro shell (como bash), puedes hacer:

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

Donde <C -> <CN> obliga a vim a pasar al modo normal, "¡editar!" le dice a vim que vuelva a cargar el archivo actual (el CR simula presionar enter), y G va al final del archivo. Al eliminar (G), es más fácil insertar el archivo mientras ingresa la entrada.


Veo el parámetro "--servername" en el hombre, sin embargo, recibí el siguiente mensaje de error: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

si haces vim --version, ¿ves + clientserver (no -clientserver, con un hypen)? Si no, muchas personas compilan vim desde la fuente usando ./configure --with-features = huge
crutux el

Sí, hay + clientserver. Tengo la versión de Ubuntu.
Fox

1

Encontré la respuesta gracias al comentario de Evan Teitelman . Mi solución está inspirada en /usr/share/vim/vimcurrent/macros/less.vim .

Hice mi propia función, pero podría mejorarse mucho.

function! Tailf()
    e
    normal G
    redraw

    sleep 1
    call Tailf()
endfunction

Y simplemente presione CTRL + C para salir de Tailf.

Para abrir un archivo de registro en modo Tailf: view -M "+call Tailf()" /path/to/logfile.log

Lo que no me gusta es la sleepllamada, que no permite hacer nada en vim durante la actualización automática. Lo mejor sería si el búfer es autónomo y se actualiza incluso si estoy en otra ventana dividida. De todos modos, es un buen comienzo. :)


2
Parece que también vuelve a leer todo el archivo, que no es lo que querías, ¿verdad?
Bernhard

Esto vuelve a cargar todo el archivo. Probablemente no sería demasiado difícil hacer un complemento basado en inotifywait y :readque espere hasta que se haya modificado un archivo y, si se ha agregado, se lee en las líneas en la parte inferior del archivo.

Sí, es cierto, vuelve a cargar todo el archivo, por lo que debe mejorarse mucho. Cuando digo que quiero esto, estoy hablando más sobre el resultado (lo que ves en la pantalla: un vim que actualiza tu archivo solo y permanece en la última línea). Desafortunadamente, no tengo suficiente conocimiento vim para hacer un buen complemento ...
Fox

@EvanTeitelman OK, ahora veo cómo usar inotifywait. Puedo saber cuando el archivo cambia. Pero, ¿cómo saber si se ha agregado (no completamente modificado) y cómo saber cuántas líneas nuevas se han agregado?
Fox

Lea el número de líneas en el archivo cada vez que el archivo cambia. Si aumenta el número de líneas, lea los cambios.

1

Un método no recursivo para lo mismo:

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

Me gusta breve y sin mucho hackeo. Puede ejecutar este oneliner desde ex (dentro de vim) cuando sea necesario (o poner cada comando en vimrc, para cuando se abren los archivos de registro).

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

(si desea saltar (casi) al final del archivo, simplemente use "G" en lugar de "lh" con las teclas de alimentación)

Explicación:

  • autoread: lee el archivo cuando se cambia desde el exterior (pero no funciona solo, no hay temporizador interno o algo así. Solo leerá el archivo cuando vim realice una acción, como un comando en ex :!
  • CursorHold * checktime: cuando el cursor no es movido por el usuario durante el tiempo especificado updatetime(que es 4000 milisegundos por defecto) checktimese ejecuta, que verifica los cambios desde fuera del archivo
  • call feedkeys("lh"): el cursor se mueve una vez, hacia la derecha y hacia la izquierda. y luego no pasa nada (... lo que significa que CursorHoldse dispara, lo que significa que tenemos un bucle )

Para detener el desplazamiento al usar call feedkeys("G"), ejecute :set noautoread: ahora vim le dirá que el archivo fue cambiado y le preguntará si desea leer los cambios o no)

Me gusta la idea de ver archivos de registro en vim (en lugar de tail -f), por ejemplo, cuando está trabajando en una sesión ssh sin screen / tmux. Además, puede copiar directamente desde el archivo de registro, si es necesario, o guardar la salida directamente o ... lo que sea que pueda hacer con vim :)

* de esta respuesta (refiriéndose a una respuesta de PhanHaiQuang y un comentario de flukus )


0

Editar: Pido disculpas, omití por completo que ya hayas intentado esto.

Puede intentar usar el complemento Tail Bundle , creo que debería hacer lo que está buscando.

Para instalar, abra tail-3.0.vba con vim y ejecute:

:so %

Reinicie y debería poder seguir un archivo desde vim así:

:Tail /path/to/file

0

SOLO para VIM 8.0+ introdujeron temporizadores, por lo que podría usar un temporizador para simular la función de cola, esto funciona bastante efectivamente en mi experiencia.

He asignado la tecla F6 para encender la cola y F7 para apagar la cola, puede personalizarlas en los comandos a continuación, también vea mi sección a continuación para PALABRAS DE PRECAUCIÓN.

Ejecute lo siguiente

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>

También puede hacer que los comandos anteriores formen parte de vimrc para que siempre los tenga.

Algunas palabras de precaución:

  • Supongo que no tiene ningún otro temporizador, por lo que timer_stopall () realmente detendrá todos los temporizadores. Puede modificar esto un poco más para obtener el ID durante timer_start y luego mantenerlo, etc., pero eso me pareció un poco de trabajo y supongo que la mayoría de la gente no usaría temporizadores.
  • Si bien está en modo de cola, sugeriría encarecidamente que no intente ejecutar ningún comando, por lo general bloquea las instancias de vim, así que POR FAVOR APAGUE LA COLA (F7) antes de que decida volver al modo de edición, ESTO ES ESTRICTAMENTE SOLO PARA VER REGISTROS.

-1

Desde Vim, ejecute:

!tail -f 

Eso suspenderá a Vim mientras el niño bifurcado se ejecuta tail -fen el búfer actual. Golpear Ctrl-Cte devuelve al búfer en Vim.


1
Eso no es vim, sino que simplemente tailhace el trabajo. Vim es portátil. Esto no es.
oligofren
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.