Rufen Sie emacsclient aus einem von Emacs aufgerufenen Programm auf

9

Ich habe ein Problem beim Anzeigen von PDF-Dokumentationsdateien mit AucTex. Ich verwende pdf-toolszum Anzeigen von PDF-Dateien in Emacs und habe emacsclient -nals 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 listingsPaket TeX-documentation-texdocanzuzeigen , wird daraus folgendes Geschlecht:

(shell-command-to-string "texdoc --view  listings")

texdocAufrufe emacsclientzum Ö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.pdfund 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).

Tyler
quelle
Warum nicht einfach verwenden texdoc -M --list listings, um die Datei zu finden, und dann verwenden find-file?
Quarky
@suvayu Nur Bequemlichkeit. Eine andere Alternative besteht darin, zu einem Terminal zu wechseln, um anzurufen, texdoc --viewund 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?
Tyler
1
Kann (async-shell-command "emacsclient -n tmp.pdf")das Problem lösen?
Name
1
@ Name interessant - (async-shell-command "emacsclient -n tmp.pdf")funktioniert, aber (async-shell-command "texdoc --view listings")nicht. Das ist also ein nützlicher Hinweis.
Tyler
1
Funktioniert das 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).
Giordano

Antworten:

5

Die Lösung besteht darin, texdocin einem asynchronen Prozess ausgeführt zu werden.

Der beste Weg, dies zu tun, ist wahrscheinlich die Verwendung von start-file-processanstelle von shell-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-processdie Ausgabe des Prozesses nicht direkt zurückgegeben wird. Stattdessen können Sie angeben, in welchem ​​Puffer die Ausgabe set-process-sentinelabgelegt 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.

Stefan
quelle
Im speziellen Fall der Ausführung texdocin 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).
Giordano
Ich habe keine Ahnung, warum die Funktion "-to-string" verwendet wurde, daher weiß ich nicht, was mit der Ausgabe des Befehls gemacht wird. Wenn diese Ausgabe benötigt wird (wie durch die Verwendung von vorgeschlagen ...-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 &").
Stefan
In den Kommentaren wird Folgendes erklärt TeX-documentation-texdoc: Die ...-to-stringVariante wird verwendet, um Benutzern mögliche Fehlermeldungen anzuzeigen (z. B. wenn keine Dokumentation gefunden wird). Darüber hinaus texdoc nonexistingpackageliefert 0, aber die Sentinel verwendet werden kann , um die Ausgabe zu analysieren.
Giordano
Dann scheint ein Sentinel die beste Option zu sein.
Stefan
Ich kann keinen Aufruf finden, der start-file-processhier 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.
Tyler
1

Wenn Sie nur eine Anfrage an Emacs zurückmelden müssen, ohne auf eine Antwort zu warten, können Sie emacsclientim Hintergrund laufen . Unter Unix-ähnlichen Betriebssystemen (Linux, macOS, Cygwin,…):

emacsclient … &

Unter nativem Windows:

start emacsclient …
Gilles 'SO - hör auf böse zu sein'
quelle
Sicher, aber in diesem speziellen Fall muss ich ein Programm (texdoc) aufrufen, das dann (emacsclient) aufruft. Die zusätzliche Umleitungsebene verursacht Probleme.
Tyler
@ Tyler texdocist asynchron (dh Sie warten nicht darauf, dass es abgeschlossen ist), nicht wahr ? Sie können also dasselbe Prinzip anwenden: Führen Sie texdoc … &den Shell-Befehl aus.
Gilles 'SO - hör auf böse zu sein'
Wir haben das in den Kommentaren unter meiner Frage versucht; Es funktioniert, wenn Sie emacsclientdirekt anrufen , aber nicht, wenn Sie anrufen texdoc.
Tyler