Automatisches Neuladen einer Datei in VIM, sobald sie sich auf der Festplatte ändert


32

Unter der Annahme, dass eine Datei keine ungespeicherten Änderungen im VIM-Puffer enthält, möchte ich, dass sie automatisch neu geladen wird, wenn sich die Datei auf der Festplatte ändert. Der häufigste Anwendungsfall hierfür ist das Aktualisieren der Arbeitskopie, in der sich die Datei befindet.

Wie kann ich das erreichen?


Ich denke, das ist, was Sie meinen, aber mein spezieller Anwendungsfall ist, wenn ich einen anderen Git-Zweig auschecke oder festschreibe, möchte ich, dass vim die Datei neu lädt.
Nathan Long

Antworten:



11

Das hat bei mir funktioniert

set autoread                                                                                                                                                                                    
au CursorHold * checktime  

Die erste Zeile war nicht genug für sich. Sie können in dich setzen.vimrc

Gutschrift an Phan Hai Quang


Die autocmd sollte nicht erforderlich sein - checktime soll intern ausgeführt werden, wenn das CursorHold-Ereignis ausgelöst wird. Mit anderen Worten, Sie lassen Vim nur eine zweite Checktime machen.
Heptite

Für mich ist es notwendig. Beste Lösung, die ich nach vielen Recherchen gefunden habe. @ Heptite, hast du Kapitel und Verse für deine Behauptung?
Tom Hale

1
@TomHale Ich habe die Vim-Dokumente durchgesehen und es heißt nicht ausdrücklich, soweit ich das beurteilen kann, aber " :help timestamp" scheint darauf hinzudeuten, dass ich derjenige bin, der sich irrt, und dass Vim nur die Überprüfung auf bestimmte Ereignisse durchführt. Daher kann es erforderlich sein, dass die automatische Prüfung häufiger durchgeführt wird.
Heptite

5

Autoread funktioniert nicht richtig. Folgendes funktioniert für mich:

Sie müssen zuerst das Skript von hier aus installieren .

Ich habe die besten Ergebnisse erzielt, indem ich die Setup-Funktion direkt aufgerufen habe.

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

Der Grund dafür ist, dass ich ein ipython / screen / vim-Setup ausführen möchte.

Sie können dies problemlos in eine erweiterte Version der Ansicht konvertieren.

Skript den Prozess ..

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
Wenn Sie eine der vim-GUIs wie gVim oder MacVim verwenden, kann der Befehl autoread problemlos in die restliche Umgebung integriert werden. Wenn Sie die Datei beispielsweise in einem anderen Programm, einem anderen Editor oder aus der Quellcodeverwaltung heraus bearbeiten und dann wieder zu vim wechseln, werden die aktualisierten Dateien automatisch gelesen. Das Problem scheint darin zu liegen, wie sich die Terminalversion von vim integriert. Die Terminal-Version kann nicht erkennen, wann Sie zwischen Programmen in der GUI oder mit Terminal-Multiplexern wie tmux wechseln. Daher kann sie zu bestimmten Zeiten nicht automatisch gelesen werden. Es wäre schön, wenn vim nur relevante Dateisystemereignisse abonnieren würde.
bames53

3

vim-autoread plugin hat bei mir bisher funktioniert:

vim-autoread

Veranlasst vim automatisch, Dateien neu zu laden, die auf die Festplatte geschrieben, aber seit dem letzten Schreiben von vim nicht im Puffer geändert wurden. Dadurch kann eine in vim geöffnete Datei mit einer anderen Anwendung bearbeitet und gespeichert werden. Wenn Sie zu vim zurückkehren und die Datei seit der letzten Änderung nicht geändert haben, wird die Datei automatisch aktualisiert, um die auf der Festplatte vorgenommenen Änderungen widerzuspiegeln, als hätten Sie Folgendes gedrückt: e manuell.


Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier einzuschließen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verlinkte Seite ändert. - Aus der Bewertung
Burgi

@ Burgi Ich habe eine Plugin-Beschreibung hinzugefügt, die erklärt, wie das Problem gelöst wird.
Wojtek Kruszewski

Ich habe es versucht, aber ich muss einen Navigationsbefehl (wie j) eingeben, um das effektive Update zu sehen. Ich habe hier ein Problem erstellt: github.com/djoshea/vim-autoread/issues/3
Martin Delille

3

aus dieser Antwort (unter Bezugnahme auf eine Antwort von PhanHaiQuang und einen Kommentar von @flukus)

Dieser Oneliner kann bei Bedarf von ex (innerhalb von vim) ausgeführt werden (oder jeder Befehl in vimrc abgelegt werden, wenn Protokolldateien geöffnet werden.)

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

Erklärung:
- autoread : Liest die Datei, wenn sie von außen geändert wird (aber es funktioniert nicht von alleine, es gibt keinen internen Timer oder ähnliches. Es liest die Datei nur, wenn vim eine Aktion ausführt, wie ein Befehl in ex :!
- CursorHold * checktime : Wenn der Cursor für die in 'updatetime' angegebene Zeit (standardmäßig 4000 Millisekunden) nicht vom Benutzer bewegt wird, wird checktime ausgeführt, um nach Änderungen von außerhalb der Datei zu suchen
- Feedkeys aufrufen ("lh") : Der Cursor wird einmal nach rechts und zurück nach links bewegt und dann passiert nichts (... was bedeutet, dass CursorHold ausgelöst wird, was bedeutet, dass wir eine Schleife haben )


lhtut nichts, wenn sich der Cursor an der letzten Position in der Zeile befindet, lhändert sich seine Position.
Mahmoud Al-Qudsi

Genau das ist der Punkt. Die Datei wird mit einem Minimum an Interaktion oder Änderungen an der Datei neu geladen. Sie könnten in die letzte oder erste Zeile springen, wenn Sie möchten (ersetzen Sie einfach lh durch gg oder G), aber das Ziel hier ist nur, die Datei in vim neu zu laden, und das ist, was dieser Einzeiler macht, nichts weiter. Was möchten Sie hier machen?
Eli

@ MahmoudAl-Qudsi ... was bedeutet, dass "lh" nur die CursorHold - Aktion auslöst (das habe ich in der Erklärung erwähnt), die dann wieder das Autoread
eli

1

Es gibt einige Plugins aufgeführt hier das könnte die Arbeit an Ihrer Version von Vim abhängig.

Ein anderer Ansatz besteht darin, den checktimeBefehl regelmäßig von einem externen Prozess an vim zu senden . Hier ist ein ShellJS-Skript, um dies zu tun (erfordert shelljs-plugin-sleep, NeoVim und 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}`) );
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.