J'ai rencontré un problème lors de l'affichage des fichiers de documentation pdf avec AucTex. J'utilise pdf-tools
pour afficher les fichiers PDF à partir d'Emacs, et j'ai défini emacsclient -n
comme visionneuse pdf par défaut (via xdg-mime sur Debian Linux). Cela fonctionne très bien dans la plupart des cas, mais cela casse la (Tex-documentation-texdoc ...)
fonction d'Auctex ( C-c ?
).
J'ai réduit le problème à une seule ligne de code. Lorsque j'essaie d'afficher la documentation du listings
package, TeX-documentation-texdoc
cela se transforme en sexp suivant:
(shell-command-to-string "texdoc --view listings")
texdoc
à son tour, appelle emacsclient
à ouvrir réellement le fichier (basé sur la façon dont j'ai configuré mon bureau via xdg). Cependant, à ce stade, Emacs se bloque et je dois quitter ( C-g
) pour reprendre le contrôle. Après cela, aucun nouveau pdf n'est ouvert. La même chose se produit si j'essaie d'appeler directement emacsclient:
(shell-command-to-string "emacsclient -n tmp.pdf")
Les deux commandes fonctionnent sur la ligne de commande (c'est-à-dire, emacsclient -n tmp.pdf
et texdoc --view listings
.
Ma question est, dans un cas comme celui-ci, comment appeler emacsclient depuis Emacs? (et je sais que je pourrais simplement ouvrir le fichier pdf avec find-file
; ce n'est pas une option ici car j'ai besoin d'appeler un processus externe (texdoc) pour trouver le fichier, et ce processus appelle ensuite emacsclient).
la source
texdoc -M --list listings
pour rechercher le fichier, puis l'utiliserfind-file
?texdoc --view
, puis à revenir à Emacs lorsqu'il ouvre le fichier. Mais je pense qu'il devrait y avoir un moyen de le faire en une seule étape depuis Emacs?(async-shell-command "emacsclient -n tmp.pdf")
résoudre le problème?(async-shell-command "emacsclient -n tmp.pdf")
fonctionne, mais pas(async-shell-command "texdoc --view listings")
non. Voilà donc un indice utile.C-u C-c ?
marche? Il affiche d'abord la liste des documents liés au package, puis ouvre la visionneuse avec(call-process "texdoc" nil 0 nil "--just-view" doc)
.Réponses:
La solution consiste à s'exécuter
texdoc
dans un processus asynchrone.La meilleure façon de le faire est probablement d'utiliser à la
start-file-process
place deshell-command-to-string
(ce qui est une fonction pratique pour le code rapide et sale quand il est plus opportun d'écrire un petit script shell que le code Elisp correspondant, mais il vaut mieux éviter autrement dans mon expérience).Mais cela nécessitera des modifications substantielles du code environnant, car
start-file-process
il ne renvoie pas directement la sortie du processus, il vous permet plutôt d'indiquer dans quel tampon placer la sortie et vous devez ensuite utiliserset-process-sentinel
une fonction de rappel qui récupère la sortie de ce tampon et fait "tout ce qui doit être fait" lorsque la commande se termine.la source
texdoc
dans AUCTeX, je trouve l'utilisation d'une sentinelle un peu exagérée, car ce n'est pas une caractéristique fondamentale (comme c'est l'ouverture de la visionneuse pour le document de sortie, auquel cas nous utilisons le sentinelle)....-to-string
), une solution asynchrone aura besoin d'un filtre de processus ou d'une sentinelle de processus. Sinon, le code peut peut-être utiliser quelque chose comme(shell-command "texdoc --view listings &")
.TeX-documentation-texdoc
: la...-to-string
variante est utilisée pour montrer aux utilisateurs d'éventuels messages d'erreur (par exemple lorsqu'aucune documentation n'est trouvée). En outre,texdoc nonexistingpackage
renvoie 0, mais la sentinelle peut être utilisée pour analyser la sortie.start-file-process
qui fonctionne réellement ici.(start-file-process "texdoc" "*texdoc*" "texdoc" "--view" "listings")
crée le tampon*texdoc*
, dans lequel est inséré "Process texdoc terminé", et le pdf ne s'ouvre jamais. La même chose se produit lorsque je configure également la visionneuse PDF xdg-mime.Si vous avez seulement besoin de renvoyer une demande à Emacs, sans attendre de réponse, vous pouvez exécuter
emacsclient
en arrière-plan. Sous OS de style Unix (Linux, macOS, Cygwin,…):Sous Windows natif:
la source
texdoc
est asynchrone (c'est-à-dire que vous n'attendez pas qu'il se termine), n'est-ce pas? Vous pouvez donc appliquer le même principe: exécuter entexdoc … &
tant que commande shell.emacsclient
directement, mais pas en appelanttexdoc
.