Ricaricamento automatico di un file in VIM non appena viene modificato sul disco


33

Supponendo che un file non abbia modifiche non salvate nel buffer VIM, vorrei che si ricaricasse automaticamente se il file cambia sul disco. Il caso d'uso più frequente per questo è quando aggiorno la copia funzionante in cui risiede il file.

Come posso raggiungere questo obiettivo?


Penso che questo sia ciò che vuoi dire, ma il mio caso d'uso specifico è quando controllo un diverso ramo o commit git, voglio che VIM ricarichi il file.
Nathan Long,

Risposte:


32

Nel tuo ~/.vimrc:

set autoread

9
Generalmente autoreadsi attiverà solo dopo aver eseguito un comando esterno. Questa risposta descrive in dettaglio le soluzioni.
Tom Hale,

Questo non funziona Segui il link @TomHale per una risposta dettagliata che lo fa
JonnyRaa

11

Questo è ciò che ha funzionato per me

set autoread                                                                                                                                                                                    
au CursorHold * checktime  

La prima riga non era abbastanza da sola. Puoi metterti dentro.vimrc

merito a Phan Hai Quang


L'autocmd non dovrebbe essere necessario: checktime dovrebbe essere eseguito internamente nello stesso momento in cui viene attivato l'evento CursorHold. In altre parole, stai solo facendo fare a Vim un secondo orario di controllo.
Heptite,

Per me è necessario. La migliore soluzione che ho trovato dopo molte ricerche. @Heptite, hai capitolo e versetto per la tua affermazione?
Tom Hale,

1
@TomHale Ho esaminato i documenti di Vim e non dice esplicitamente, per quanto posso dire, ma " :help timestamp" sembrerebbe indicare che sono io quello in errore e che Vim esegue solo il controllo su eventi specifici, quindi potrebbe essere necessario autocmd per fare in modo che controlli più frequentemente.
Eptita

5

Autoread non funziona correttamente. Per me funziona quanto segue:

Devi prima installare lo script da qui .

Ho ottenuto i migliori risultati chiamando direttamente la funzione di installazione, in questo modo.

let autoreadargs={'autoread':1} 
execute WatchForChanges("*",autoreadargs) 

Il motivo di ciò è che voglio eseguire un'installazione ipython / screen / vim.

Puoi facilmente convertirlo in una versione avanzata della vista.

script il processo ..

mkdir -p ~/bin
cat <<`OUT` > ~/bin/vimviewer
#!/usr/bin/env sh
exec vim -n --cmd "source /home/bryan/.vim/.vimrc.watchforchanges | let autoreadargs={'autoread':1} | execute WatchForChanges('*',autoreadargs)" $@
`OUT`

chmod 755 ~/bin/vimviewer
vimview test.txt

1
Se stai usando una delle GUI di vim come gVim o MacVim, il comando di autoread si integra perfettamente con il resto dell'ambiente. Ad esempio, la modifica del file in qualche altro programma, un altro editor o dal controllo del codice sorgente, quindi il passaggio a VIM autoreadead i file aggiornati. Il problema sembra riguardare l'integrazione della versione terminale di vim. La versione del terminale non è in grado di stabilire quando si passa da un programma all'altro nella GUI o quando si utilizzano i multiplexer terminali come tmux, quindi non riesce a eseguire la lettura automatica nei momenti pertinenti. Sarebbe bello se vim si iscrivesse agli eventi rilevanti del file system.
bames53,

3

Finora il plugin vim-autoread ha funzionato per me:

vim-AutoRead

Fa sì che vim ricarichi automaticamente i file che sono stati scritti sul disco ma non modificati nel buffer dall'ultima scrittura da vim. Ciò consente a un file aperto in vim di essere modificato utilizzando un'altra applicazione e salvato. Al ritorno su vim, purché non sia stato modificato il file dall'ultima modifica, il file verrà automaticamente aggiornato per riflettere le modifiche apportate sul disco, come se si fosse premuto: e manualmente.


Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il collegamento come riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. - Dalla recensione
Burgi,

@Burgi Ho aggiunto la descrizione del plugin che spiega come risolve il problema.
Wojtek Kruszewski,

L'ho provato ma devo digitare un comando di navigazione (come j) per vedere l'aggiornamento effettivo. Ho creato un problema qui su questo: github.com/djoshea/vim-autoread/issues/3
Martin Delille,

3

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

È possibile 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")

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) viene eseguito il checktime, che controlla le modifiche al di fuori 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 viene attivato CursorHold, il che significa che abbiamo un loop )


lhnon fa nulla, se il cursore si trova sull'ultima posizione sulla linea, lhcambierà la sua posizione.
Mahmoud Al-Qudsi,

Esatto, questo è il punto. Il file viene ricaricato con il minimo di interazione o modifiche al file. Puoi saltare all'ultima o alla prima riga se vuoi (basta sostituire lh con gg o G), ma l'obiettivo qui è solo quello di ricaricare il file in vim, e questo è quello che è fatto da questo one-liner, niente di più. Cosa ti piace fare qui?
eli,

@ MahmoudAl-Qudsi ... significa che "lh" innesca semplicemente il CursorHold - azione (di cui ho parlato nella Spiegazione), che poi innesca nuovamente la lettura automatica
eli

1

Ci sono alcuni plugin elencati qui che potrebbero funzionare a seconda della tua versione di Vim.

Un altro approccio è inviare periodicamente il checktimecomando a vim da un processo esterno. Ecco uno script ShellJS per fare questo (richiede shelljs-plugin-sleep, NeoVim e nvr)

while (true) {
  sleep(15);
  var servernames = exec('nvr --serverlist').trim().split('\n');
  if (!servernames.length || !servernames[0]) {
    continue;
  }
  servernames.forEach(
    (sn) => exec(`nvr -c "checktime" --servername ${sn}`) );
}
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.