Der Grund, dass dies nicht funktioniert, wenn die Datei bereits geöffnet ist, weil das Laden einer Datei asynchron ist; Der Befehl zum Öffnen der Datei wird sofort zurückgegeben und die Datei wird im Hintergrund geladen, wenn sie nicht bereits geöffnet ist.
Wenn Sie also das erste Mal den Befehl ausführen, wird der Befehl move_to
nicht ausgeführt, da er bereits am Ende eines leeren Puffers steht. Wenn die Datei jedoch bereits geladen wurde, wird der erwartete Vorgang ausgeführt.
Um dies zu umgehen, müssen Sie feststellen, ob die Datei noch geladen ist, und den Aufruf verzögern, um bis zum Ende der Datei zu springen, bis sie beendet ist. Ein Beispiel dafür ist die folgende:
import sublime
import sublime_plugin
import os
class OpenLogCommand(sublime_plugin.TextCommand):
def run(self, edit):
log_name = self.view.file_name()[:-3] + "log"
log_view = self.view.window().open_file(log_name)
if log_view.is_loading():
log_view.settings().set("_goto_eol", True)
else:
log_view.run_command("move_to", {"to": "eof"})
def is_enabled(self):
fname = self.view.file_name()
if fname is not None and not fname.endswith(".log"):
return os.path.isfile(fname[:-3] + "log")
return False
class OpenLogListener(sublime_plugin.EventListener):
def on_load(self, view):
if view.settings().get("_goto_eol", False):
view.settings().erase("_goto_eol")
view.run_command("move_to", {"to": "eof"})
Ein Problem mit Ihrer vorhandenen Version davon ist, dass die file_name()
Methode gibt None
, wenn die Datei noch nicht auf Platte gespeichert wurde. Wenn Sie diesen Befehl für eine nicht gespeicherte Datei ausführen, wird ein Fehler in der Konsole generiert. Dies ist harmlos, aber ein wenig unrein, da es ein Fehler sein könnte, wenn Sie andere Probleme haben und diese Fehler in der Konsole sehen.
Hier wird der Befehl nur aktiviert, wenn die Datei gespeichert wurde, um diese Art von Problem zu stoppen. Es wird auch nur aktiviert, wenn es sich nicht bereits um eine Protokolldatei handelt (da dies redundant wäre) und wenn eine zugehörige Protokolldatei tatsächlich vorhanden ist.
Wenn ein Befehl deaktiviert ist, können Sie ihn nicht ausführen. Das bedeutet, dass es auch nicht in der Befehlspalette angezeigt wird und in Menüs ausgegraut erscheint (vorausgesetzt, Sie haben es zu einem der beiden hinzugefügt).
Wenn Sie den Befehl ausführen, ruft er zuerst open_file
auf, um die zugehörige Protokolldatei zu öffnen, und fragt dann die Ansicht "Laden Sie noch?". Wenn die Ansicht NEIN sagt, bedeutet dies, dass die Datei bereits geöffnet ist und wir sofort zum Ende der Datei springen können.
Wenn die Ansicht JA zu dieser Frage sagt, setzen wir eine temporäre Einstellung in der Ansicht, so dass wir wissen, dass wenn der Inhalt dieser Ansicht fertig geladen ist, wir zum Ende des Puffers springen wollen.
Der Ereignis-Listener fragt jede Ansicht nach dem Laden ab, ob diese Einstellung festgelegt wurde. Wenn dies der Fall ist, wird die Einstellung entfernt und dann zum Ende der Datei gesprungen.
[Bearbeiten]
Wie unten in den Kommentaren erwähnt, ist der move_to
Befehl verhält sich etwas anders für eine Datei, die im Vergleich zu einer Datei bereits geöffnet ist, das Laden gerade beendet hat.
Ich bin nicht ganz sicher, warum das der Fall ist, aber ich vermute, dass es eine subtile Wechselwirkung zwischen der on_load
Benachrichtigung geliefert wird, wenn der Dateiinhalt geladen wurde, aber noch nicht angezeigt oder etwas in diesen Zeilen, obwohl dies ist nur eine Vermutung.
In jedem Fall ist die zweckmäßigste fix wäre eine leichte Modifikation des Ereignis-Listener zu machen, indem der Teil des Codes oben mit diesem statt ersetzen:
class OpenLogListener(sublime_plugin.EventListener):
def on_load(self, view):
if view.settings().get("_goto_eol", False):
view.settings().erase("_goto_eol")
sublime.set_timeout(lambda: view.run_command("move_to", {"to": "eof"}), 1)
Dies ändert die Dinge so ein wenig nach oben, dass Der Aufruf des Befehls move_to
erfolgt effektiv, nachdem die gesamte Ereignisbehandlung abgeschlossen wurde. Das scheint das Problem zumindest auf meiner Testmaschine zu lösen.
Danke für die tolle Erklärung! Ich habe ein kleines Problem mit dem Befehl eof. Wenn ich Strg + Ende in einem beliebigen Puffer drücke, wird der Cursor in die letzte Zeile gesetzt und die letzte Zeile bleibt am unteren Rand der Seite, wodurch die Textmenge auf dem Bildschirm maximiert wird. Mit diesem Code funktioniert es so, wenn die .log-Datei bereits geöffnet ist. Wenn es noch nicht geöffnet ist, legt es die letzte Textzeile in die erste Zeile des Bildschirms, zeigt überhaupt keinen Text und ich muss nach oben scrollen, um den Text zu sehen. Ich habe bisher viel auf Google gesucht, ohne Erfolg. Weißt du, wie man das löst? – Emerson
Hmm interessant. Ich bin mir nicht sicher, warum das passiert, obwohl es verdächtig scheint. Ich habe die Antwort bearbeitet, um eine mögliche Problemumgehung bereitzustellen. Lassen Sie mich wissen, ob das für Sie funktioniert oder nicht. – OdatNurd
Perfekt! Vielen Dank! – Emerson