Me he encontrado con un problema al ver los archivos de documentación en pdf con AucTex. Utilizo pdf-tools
para ver archivos PDF desde Emacs, y lo configuré emacsclient -n
como mi visor de PDF predeterminado (a través de xdg-mime en Debian Linux). Esto funciona bien en la mayoría de las circunstancias, pero rompe la (Tex-documentation-texdoc ...)
función de Auctex ( C-c ?
).
He reducido el problema a una sola línea de código. Cuando intento ver la documentación del listings
paquete, lo TeX-documentation-texdoc
convierto en el siguiente sexp:
(shell-command-to-string "texdoc --view listings")
texdoc
a su vez llama emacsclient
a abrir realmente el archivo (según cómo configuré mi escritorio a través de xdg). Sin embargo, en este punto, el Emacs se cuelga y necesito salir ( C-g
) para recuperar el control. Después de eso, no se abre un nuevo pdf. Lo mismo sucede si intento llamar a emacsclient directamente:
(shell-command-to-string "emacsclient -n tmp.pdf")
Ambos comandos funcionan en la línea de comando (es decir, emacsclient -n tmp.pdf
y texdoc --view listings
.
Mi pregunta es, en un caso como este, ¿cómo llamo a emacsclient desde Emacs? (y sé que podría abrir el archivo pdf con find-file
; esa no es una opción aquí, ya que necesito llamar a un proceso externo (texdoc) para encontrar el archivo, y ese proceso invoca a emacsclient).
fuente
texdoc -M --list listings
para encontrar el archivo y luego usarfind-file
?texdoc --view
y luego volver a Emacs cuando abre el archivo. Pero creo que debería haber una manera de hacer esto en un solo paso desde Emacs.(async-shell-command "emacsclient -n tmp.pdf")
resolver el problema?(async-shell-command "emacsclient -n tmp.pdf")
funciona, pero no(async-shell-command "texdoc --view listings")
no. Esa es una pista útil.C-u C-c ?
? Primero muestra la lista de documentos relacionados con el paquete, luego abre el visor con(call-process "texdoc" nil 0 nil "--just-view" doc)
.Respuestas:
La solución es ejecutarse
texdoc
dentro de un proceso asincrónico.Probablemente, la mejor manera de hacerlo es usarlo en
start-file-process
lugar deshell-command-to-string
(que es una función práctica para el código rápido y sucio cuando es más conveniente escribir un pequeño script de shell que el código Elisp correspondiente, pero por lo demás es mejor evitarlo en mi experiencia).Pero requerirá cambios sustanciales en el código circundante, ya
start-file-process
que no devuelve la salida del proceso directamente, sino que le permite indicar en qué búfer colocar la salida y luego debe usarset-process-sentinel
una función de devolución de llamada que recupere la salida de ese búfer y hace "lo que sea necesario hacer con él" cuando finaliza el comando.fuente
texdoc
en AUCTeX, considero que el uso de un centinela es una exageración, ya que esta no es una característica fundamental (como es la apertura del visor para el documento de salida, en cuyo caso utilizamos el centinela)....-to-string
), una solución asíncrona necesitará un filtro de proceso o un centinela de proceso. Si no, entonces el código puede usar algo como(shell-command "texdoc --view listings &")
.TeX-documentation-texdoc
: la...-to-string
variante se utiliza para mostrar a los usuarios posibles mensajes de error (por ejemplo, cuando no se encuentra documentación). Además,texdoc nonexistingpackage
devuelve 0, pero el centinela puede usarse para analizar la salida.start-file-process
eso realmente funciona aquí.(start-file-process "texdoc" "*texdoc*" "texdoc" "--view" "listings")
crea el búfer*texdoc*
, en el que se inserta "Proceso texdoc terminado", y el pdf nunca se abre. Lo mismo sucede cuando configuro el visor de pdf xdg-mime para que también lo muestre.Si solo necesita retroalimentar una solicitud a Emacs, sin esperar una respuesta, puede ejecutarla
emacsclient
en segundo plano. En sistemas operativos de estilo Unix (Linux, macOS, Cygwin, ...):Bajo Windows nativo:
fuente
texdoc
es asíncrono (es decir, no estás esperando que se complete), ¿no? Entonces podría aplicar el mismo principio: ejecutartexdoc … &
como el comando de shell.emacsclient
directamente, pero no cuando se llamatexdoc
.