Ich habe ein Problem beim Anzeigen von PDF-Dokumentationsdateien mit AucTex. Ich verwende pdf-tools
zum Anzeigen von PDF-Dateien in Emacs und habe emacsclient -n
als Standard-PDF-Viewer festgelegt (über xdg-mime unter Debian Linux). Dies funktioniert in den meisten Fällen (Tex-documentation-texdoc ...)
einwandfrei, unterbricht jedoch die Funktion von Auctex ( C-c ?
).
Ich habe das Problem auf eine einzige Codezeile eingegrenzt. Wenn ich versuche, die Dokumentation für das listings
Paket TeX-documentation-texdoc
anzuzeigen , wird daraus folgendes Geschlecht:
(shell-command-to-string "texdoc --view listings")
texdoc
Aufrufe emacsclient
zum Öffnen der Datei (basierend darauf, wie ich meinen Desktop über xdg konfiguriert habe). Zu diesem Zeitpunkt hängt der Emacs jedoch und ich muss beenden ( C-g
), um die Kontrolle zurückzugewinnen. Danach wird kein neues PDF geöffnet. Das gleiche passiert, wenn ich versuche, emacsclient direkt aufzurufen:
(shell-command-to-string "emacsclient -n tmp.pdf")
Beide Befehle arbeiten in der Befehlszeile (dh emacsclient -n tmp.pdf
und texdoc --view listings
.
Meine Frage ist in einem solchen Fall, wie ich emacsclient innerhalb von Emacs aufrufe. (und ich weiß, dass ich die PDF-Datei einfach mit öffnen könnte find-file
; das ist hier keine Option, da ich einen externen Prozess (texdoc) aufrufen muss, um die Datei zu finden, und dieser Prozess dann emacsclient aufruft).
quelle
texdoc -M --list listings
, um die Datei zu finden, und dann verwendenfind-file
?texdoc --view
und dann wieder zu Emacs zu wechseln, wenn die Datei geöffnet wird. Aber ich denke, es sollte eine Möglichkeit geben, dies in einem einzigen Schritt von Emacs aus zu tun?(async-shell-command "emacsclient -n tmp.pdf")
das Problem lösen?(async-shell-command "emacsclient -n tmp.pdf")
funktioniert, aber(async-shell-command "texdoc --view listings")
nicht. Das ist also ein nützlicher Hinweis.C-u C-c ?
? Es zeigt zuerst die Liste der Dokumente an, die sich auf das Paket beziehen, und öffnet dann den Viewer mit(call-process "texdoc" nil 0 nil "--just-view" doc)
.Antworten:
Die Lösung besteht darin,
texdoc
in einem asynchronen Prozess ausgeführt zu werden.Der beste Weg, dies zu tun, ist wahrscheinlich die Verwendung von
start-file-process
anstelle vonshell-command-to-string
(was eine praktische Funktion für schnellen und schmutzigen Code ist, wenn es zweckmäßiger ist, ein kleines Shell-Skript als den entsprechenden Elisp-Code zu schreiben, aber meiner Erfahrung nach besser vermieden wird).Es sind jedoch wesentliche Änderungen am umgebenden Code erforderlich, da
start-file-process
die Ausgabe des Prozesses nicht direkt zurückgegeben wird. Stattdessen können Sie angeben, in welchem Puffer die Ausgabeset-process-sentinel
abgelegt werden soll, und dann müssen Sie eine Rückruffunktion verwenden, die die Ausgabe aus diesem Puffer abruft macht "was auch immer damit gemacht werden muss", wenn der Befehl beendet ist.quelle
texdoc
in AUCTeX empfinde ich die Verwendung eines Sentinels als etwas übertrieben, da dies keine grundlegende Funktion ist (wie das Öffnen des Viewers für das Ausgabedokument. In diesem Fall verwenden wir das Wächter)....-to-string
), benötigt eine asynchrone Lösung entweder einen Prozessfilter oder einen Prozess-Sentinel. Wenn nicht, kann der Code möglicherweise so etwas wie verwenden(shell-command "texdoc --view listings &")
.TeX-documentation-texdoc
: Die...-to-string
Variante wird verwendet, um Benutzern mögliche Fehlermeldungen anzuzeigen (z. B. wenn keine Dokumentation gefunden wird). Darüber hinaustexdoc nonexistingpackage
liefert 0, aber die Sentinel verwendet werden kann , um die Ausgabe zu analysieren.start-file-process
hier tatsächlich funktioniert. Erstellt den(start-file-process "texdoc" "*texdoc*" "texdoc" "--view" "listings")
Puffer*texdoc*
, in den "Process texdoc beendet" eingefügt wird, und das PDF wird nie geöffnet. Das gleiche passiert, wenn ich den pdf-Viewer xdg-mime so einstelle, dass er auch angezeigt wird.Wenn Sie nur eine Anfrage an Emacs zurückmelden müssen, ohne auf eine Antwort zu warten, können Sie
emacsclient
im Hintergrund laufen . Unter Unix-ähnlichen Betriebssystemen (Linux, macOS, Cygwin,…):Unter nativem Windows:
quelle
texdoc
ist asynchron (dh Sie warten nicht darauf, dass es abgeschlossen ist), nicht wahr ? Sie können also dasselbe Prinzip anwenden: Führen Sietexdoc … &
den Shell-Befehl aus.emacsclient
direkt anrufen , aber nicht, wenn Sie anrufentexdoc
.