Come faccio a far sì che Vim si comporti come "tail -f"?


36

Vorrei sapere se esiste un modo per far comportare Vim tail -f.
Anche il miglior plug-in Vim che ho trovato finora non fa quello che mi aspetto.

Voglio davvero vedere l'aggiornamento dei file in tempo reale . Anche se sono lontano dalla tastiera, voglio che Vim ricarichi costantemente il buffer e salti all'ultima riga.

Come fare questo?
(Non voglio ricaricare l'intero file, poiché alcuni file di registro sono molto grandi. La cosa migliore è caricare solo le ultime righe, come tail -ffa.)


2
Perché deve essere dentro vim? Cosa c'è che non va tail -f?
Sven,

1
Perché voglio il potere di VIM quando leggo i file di registro. Come essere in grado di cercare un modello e soprattutto apprezzare l'evidenziazione della sintassi. Ho creato la mia evidenziazione della sintassi per alcuni file di registro (bind, apache, ecc.).

Potresti essere interessato a autoread e FileChangedShell >: help autoread>: help FileChangedShell
gsi-frank

2
Solo per la ricerca, potresti fare less +Finvece di tail -f. Non ti dà l'evidenziazione della sintassi però.
Dennis Kaarsemaker,

Risposte:


28

Non puoi farti vimcomportare come tail -f. Puoi farti lesscomportare come una combinazione di vime tail -fsebbene.

Inoltra per sempre (segui) la modalità

lessha una modalità forward per sempre a cui puoi accedere premendo Fo passando +Fad essa come argomento.

$ less +F

In questa modalità, lesssi comporta come tail -fse non smettesse di leggere quando raggiunge la fine di un file. Si aggiorna costantemente con nuovi dati dal file. Per uscire da questa modalità, premere Ctrlc.

Evidenziazione della sintassi

lesssupporta il filtraggio automatico dei dati che legge. Esiste un programma chiamato source-highlight che può eseguire l'evidenziazione del codice sorgente di base. Viene fornito con uno script che funziona bene con less. Per usarlo, basta impostare la LESSOPENvariabile ambientale in modo appropriato.

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

Devi anche dire lessdi passare sequenze di escape del terminale non elaborate (che indicano al tuo terminale come colorare il testo) passandogli la -Rbandiera. Puoi dire lessdi far finta che venga sempre passato il -Rflag impostando la LESSvariabile ambientale.

 export LESS=' -R '

Quando lessnon è abbastanza

Sebbene lessabbia combinazioni di tasti simili a vi, non è proprio lo stesso di Vim. A volte sembra estraneo e manca di funzionalità importanti come l'integrazione dei tag e la possibilità di modificare il testo.

È possibile effettuare la lesschiamata Vim (supponendo EDITOR=vim) sul file attualmente visualizzato premendo v. lessposizionerà anche il cursore nella posizione corretta all'interno di Vim. Quando esci da Vim, ti ritroverai a less. Se hai apportato modifiche al file mentre eri in Vim, verranno riflesse less.


5
vim --servername TAIL_VIM /tmp/somefile

Ora, in un'altra shell (come bash), puoi fare:

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

Dove <C -> <CN> forza vim per passare alla modalità normale, "modifica!" dice a vim di ricaricare il file corrente (il CR simula premendo invio) e G va in fondo al file. La rimozione di (G) semplifica l'inserimento del file durante l'input.


Vedo il parametro "--servername" nell'uomo, tuttavia ho ricevuto il seguente messaggio di errore: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 fai vim --version vedi + clientserver (non -clientserver, con un hypen)? In caso contrario, molte persone compilano vim dal sorgente usando ./configure --with-features = huge
crutux

Sì, c'è + clientserver. Ho la versione di Ubuntu.
Fox,

1

Ho trovato la risposta grazie al commento di Evan Teitelman . La mia soluzione è ispirata a /usr/share/vim/vimcurrent/macros/less.vim .

Ho fatto la mia funzione, ma potrebbe essere migliorata molto.

function! Tailf()
    e
    normal G
    redraw

    sleep 1
    call Tailf()
endfunction

E basta premere CTRL + C per uscire da Tailf.

Per aprire un file di registro in modalità Tailf: view -M "+call Tailf()" /path/to/logfile.log

Quello che non mi piace, è la sleepchiamata, che non consente di fare nulla in vim durante l'aggiornamento automatico. Il migliore sarebbe se il buffer è autonomo e si aggiorna anche se mi trovo in un'altra finestra divisa. Ad ogni modo, è un buon inizio. :)


2
Sembra che rileggi anche l'intero file, che non è quello che volevi, giusto?
Bernhard,

Questo ricarica l'intero file. Probabilmente non sarebbe troppo difficile creare un plugin basato su inotifywait e :readche attende fino a quando un file è stato modificato e, se è stato aggiunto, legge nelle righe in fondo al file.

Sì, è vero, ricarica l'intero file, quindi questo deve essere molto migliorato. Quando dico che lo voglio, parlo più del risultato (quello che vedi sullo schermo: un vim che aggiorna il tuo file da solo e rimane sull'ultima riga). Sfortunatamente non ho abbastanza conoscenza di VIM per creare un bel plugin ...
Fox,

@EvanTeitelman OK, vedo come usare inotifywait ora. Posso sapere ogni volta che il file cambia. Ma come sapere se è stato aggiunto (non completamente modificato) e come sapere quante nuove linee sono state aggiunte?
Fox,

Leggere il numero di righe nel file ogni volta che il file cambia. Se il numero di righe aumenta, leggi le modifiche.

1

Un metodo non ricorsivo per lo stesso:

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

Mi piace breve e senza molto hacking. Puoi eseguire questo oneliner da ex (con vim) quando necessario (o mettere ogni comando in vimrc, per quando vengono aperti i file di registro).

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

(se vuoi saltare (quasi) alla fine del file, usa semplicemente "G" invece di "lh" con i feedkeys)

Spiegazione:

  • autoread: legge il file quando viene modificato dall'esterno (ma non funziona da solo, non esiste un timer interno o qualcosa del genere. Leggerà il file solo quando vim esegue un'azione, come un comando in ex :!
  • CursorHold * checktime: quando il cursore non viene spostato dall'utente per il tempo specificato in updatetime(che è di default 4000 millisecondi) checktimeviene eseguito, che controlla le modifiche dall'esterno del file
  • call feedkeys("lh"): il cursore viene spostato una volta, a destra e indietro a sinistra. e poi non succede nulla (... il che significa che CursorHoldviene attivato, il che significa che abbiamo un loop )

Per interrompere lo scorrimento durante l'utilizzo call feedkeys("G"), esegui :set noautoread- ora vim dirà, che il file è stato modificato e chiedi se si desidera leggere le modifiche o meno)

Mi piace l'idea di guardare i file di log in vim (invece di tail -f), ad esempio quando lavori in una sessione ssh senza schermo / tmux. Inoltre, puoi copiare direttamente dal file di registro, se necessario, o salvare l'output direttamente o ... qualunque cosa tu possa fare con vim :)

* da questa risposta (riferendosi a una risposta di PhanHaiQuang e un commento di flukus )


0

Modifica: mi scuso, completamente ignorato che hai già provato questo.

Puoi provare a utilizzare il plug-in Tail Bundle , penso che dovrebbe fare quello che stai cercando.

Per installare, apri tail-3.0.vba con vim ed esegui:

:so %

Riavvia e dovresti essere in grado di eseguire la coda di un file da VIM in questo modo:

:Tail /path/to/file

0

SOLO per VIM 8.0+ hanno introdotto i timer, quindi è possibile utilizzare un timer per simulare la funzione di coda, questo funziona abbastanza efficacemente nella mia esperienza.

Ho mappato il tasto F6 per attivare la coda e F7 per disattivare la coda, è possibile personalizzare quelli nei comandi seguenti, vedere anche la mia sezione di seguito per PAROLE DI ATTENZIONE.

Esegui quanto segue

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>

Puoi anche rendere i comandi precedenti parte di vimrc in modo da averli sempre.

Alcune parole di cautela:

  • Presumo che tu non abbia altri timer, quindi timer_stopall () effettivamente fermerà tutti i timer. Potresti modificarlo un po 'di più per ottenere l'ID durante timer_start e poi tenerlo premuto, ecc. Ma mi è sembrato un po' di lavoro e suppongo che la maggior parte delle persone non userebbe i timer.
  • mentre è in modalità coda, consiglio vivamente di non provare a eseguire alcun comando, di solito si arresta in modo anomalo le istanze vim, quindi PER FAVORE SPEGNERE TAIL (F7) prima di decidere di tornare in modalità di modifica, questo è SOLO STRETTAMENTE PER VISUALIZZARE I LOG.

-1

Da Vim, esegui:

!tail -f 

Ciò sospenderà Vim mentre il figlio biforcuto viene eseguito tail -fsul buffer corrente. Colpire Ctrl-Cti riporta al buffer in Vim.


1
Questo non è vim, ma è semplice tailfare il lavoro. Vim è portatile. Questo non è.
oligofren
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.