Chiama emacsclient da un programma chiamato da Emacs


9

Ho riscontrato un problema durante la visualizzazione dei file di documentazione pdf con AucTex. Uso pdf-toolsper visualizzare i file PDF da Emacs e ho impostato emacsclient -nil mio visualizzatore di PDF predefinito (tramite xdg-mime su Debian Linux). Funziona bene nella maggior parte dei casi, ma interrompe la (Tex-documentation-texdoc ...)funzione di Auctex ( C-c ?).

Ho ridotto il problema a una singola riga di codice. Quando provo a visualizzare la documentazione per il listingspacchetto, lo TeX-documentation-texdoctrasformo nel seguente sexp:

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

texdoca sua volta chiama emacsclientper aprire effettivamente il file (in base a come ho configurato il mio desktop tramite xdg). Tuttavia, a questo punto, Emacs si blocca e ho bisogno di uscire ( C-g) per riprendere il controllo. Successivamente, non viene aperto alcun nuovo pdf. La stessa cosa succede se provo a chiamare direttamente emacsclient:

(shell-command-to-string "emacsclient -n tmp.pdf")

Entrambi i comandi funzionano dalla riga di comando (cioè, emacsclient -n tmp.pdfe texdoc --view listings.

La mia domanda è, in un caso come questo, come posso chiamare emacsclient da Emacs? (e so che potrei semplicemente aprire il file pdf con find-file; questa non è un'opzione qui perché ho bisogno di chiamare un processo esterno (texdoc) per trovare il file, e quel processo invoca emacsclient).


Perché non utilizzare solo texdoc -M --list listingsper trovare il file e quindi utilizzare find-file?
Quarky,

@suvayu Solo praticità. Un'altra alternativa è passare a un terminale per chiamare texdoc --viewe quindi tornare a Emacs quando apre il file. Ma penso che dovrebbe esserci un modo per farlo in un solo passo da Emacs?
Tyler,

1
Può (async-shell-command "emacsclient -n tmp.pdf")risolvere il problema?
Nome

1
@Nome interessante - (async-shell-command "emacsclient -n tmp.pdf")funziona, ma non lo (async-shell-command "texdoc --view listings")fa. Quindi questo è un indizio utile.
Tyler,

1
Funziona C-u C-c ?? Prima mostra l'elenco dei documenti relativi al pacchetto, quindi apre il visualizzatore con (call-process "texdoc" nil 0 nil "--just-view" doc).
giordano,

Risposte:


5

La soluzione è eseguire texdocall'interno di un processo asincrono.

Il modo migliore per farlo è probabilmente quello di usare start-file-processal posto di shell-command-to-string(che è una funzione utile per il codice rapido e sporco quando è più opportuno scrivere un piccolo script di shell che il codice Elisp corrispondente, ma è comunque meglio evitare nella mia esperienza).

Ma richiederà modifiche sostanziali al codice circostante, poiché start-file-processnon restituisce direttamente l'output del processo, invece ti consente di indicare in quale buffer posizionare l'output e quindi devi utilizzare set-process-sentineluna funzione di callback che recupera l'output da quel buffer e fa "tutto ciò che deve essere fatto con esso" al termine del comando.


Nel caso specifico di esecuzione texdocin AUCTeX trovo l'uso di una sentinella un po 'eccessivo, dal momento che questa non è una caratteristica fondamentale (come se fosse l'apertura del visualizzatore per il documento di output, nel qual caso utilizziamo il sentinella).
giordano,

Non ho idea del perché sia ​​stata utilizzata la funzione "-to-string", quindi non so cosa viene fatto con l'output del comando. Se è necessario questo output (come suggerito dall'uso di ...-to-string), una soluzione asincrona avrà bisogno di un filtro di processo o di un proces-sentinel. In caso contrario, il codice può forse usare qualcosa di simile (shell-command "texdoc --view listings &").
Stefan,

È spiegato nei commenti a TeX-documentation-texdoc: la ...-to-stringvariante viene utilizzata per mostrare agli utenti possibili messaggi di errore (ad esempio quando non viene trovata alcuna documentazione). Inoltre, texdoc nonexistingpackagerestituisce 0, ma la sentinella può essere utilizzata per analizzare l'output.
giordano,

Quindi una sentinella sembra essere l'opzione migliore.
Stefan,

Non riesco a trovare un'invocazione start-file-processche funzioni effettivamente qui. (start-file-process "texdoc" "*texdoc*" "texdoc" "--view" "listings")crea il buffer *texdoc*, a cui è inserito "Elaborazione texdoc terminata" e il pdf non si apre mai. La stessa cosa accade quando imposto anche il visualizzatore di pdf xdg-mime per dimostrarlo.
Tyler,

1

Se devi solo inviare una richiesta a Emacs, senza attendere una risposta, puoi eseguire emacsclientin background. Sotto sistemi operativi in ​​stile Unix (Linux, macOS, Cygwin, ...):

emacsclient … &

Sotto Windows nativo:

start emacsclient …

Certo, ma in questo caso particolare ho bisogno di chiamare un programma (texdoc) che poi chiama (emacsclient). Il livello aggiuntivo di reindirizzamento sta causando problemi.
Tyler,

@Tyler texdocè asincrono (ovvero non stai aspettando che venga completato), vero? Quindi potresti applicare lo stesso principio: esegui texdoc … &come comando shell.
Gilles 'SO- smetti di essere malvagio' il

Lo abbiamo provato nei commenti sotto la mia domanda; funziona quando si chiama emacsclientdirettamente, ma non quando si chiama texdoc.
Tyler,
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.