Ligue para o emacsclient a partir de um programa chamado Emacs

9

Ocorreu um problema ao exibir arquivos de documentação em pdf com o AucTex. Eu uso pdf-toolspara visualizar arquivos PDF no Emacs e defini emacsclient -ncomo meu visualizador de PDF padrão (via xdg-mime no Debian Linux). Isso funciona bem na maioria das circunstâncias, mas quebra a (Tex-documentation-texdoc ...)função de Auctex ( C-c ?).

Eu reduzi o problema a uma única linha de código. Quando tento visualizar a documentação do listingspacote, TeX-documentation-texdoctransforma isso no seguinte sexp:

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

texdocpor sua vez, chama emacsclientpara realmente abrir o arquivo (com base em como eu configurei minha área de trabalho via xdg). No entanto, neste momento, o Emacs trava e eu preciso sair ( C-g) para recuperar o controle. Depois disso, nenhum novo pdf é aberto. O mesmo acontece se eu tentar ligar diretamente para o emacsclient:

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

Ambos os comandos funcionam na linha de comando (ou seja, emacsclient -n tmp.pdfe texdoc --view listings.

Minha pergunta é, em uma instância como esta, como chamo o emacsclient de dentro do Emacs? (e eu sei que eu poderia simplesmente abrir o arquivo pdf find-file; isso não é uma opção aqui, pois preciso chamar um processo externo (texdoc) para encontrar o arquivo, e esse processo chama o emacsclient).

Tyler
fonte
Por que não usar apenas texdoc -M --list listingspara encontrar o arquivo e depois usá-lo find-file?
Quarky
@suvayu Apenas conveniência. Outra alternativa é mudar para um terminal para ligar texdoc --viewe depois voltar para o Emacs quando ele abrir o arquivo. Mas acho que deveria haver uma maneira de fazer isso em uma única etapa do Emacs?
Tyler
11
Pode (async-shell-command "emacsclient -n tmp.pdf")resolver o problema?
Nome
11
@ Nome interessante - (async-shell-command "emacsclient -n tmp.pdf")funciona, mas não (async-shell-command "texdoc --view listings"), não. Então essa é uma pista útil.
Tyler
11
Funciona C-u C-c ?? Primeiro, mostra a lista de documentos relacionados ao pacote e abre o visualizador com (call-process "texdoc" nil 0 nil "--just-view" doc).
23716 giordano

Respostas:

5

A solução é executar texdocdentro de um processo assíncrono.

A melhor maneira de fazer isso é provavelmente usar em start-file-processvez de shell-command-to-string(que é uma função útil para código rápido e sujo, quando é mais conveniente escrever um pequeno script de shell que o código Elisp correspondente, mas é melhor evitar isso em minha experiência).

Mas isso exigirá alterações substanciais no código circundante, já start-file-processque não retorna a saída do processo diretamente. Em vez disso, permite indicar em qual buffer colocar a saída e você precisará usar set-process-sentineluma função de retorno de chamada que busca a saída desse buffer e faz "o que precisa ser feito com ele" quando o comando termina.

Stefan
fonte
No caso específico da execução texdocno AUCTeX, considero o uso de um sentinela um pouco exagerado, já que esse não é um recurso fundamental (como a abertura do visualizador para o documento de saída). Nesse caso, usamos o sentinela).
Giordano
Não faço ideia por que a função "-to-string" foi usada, portanto não sei o que é feito com a saída do comando. Se essa saída for necessária (como sugerido pelo uso de ...-to-string), uma solução assíncrona precisará de um filtro de processo ou de um processo-sentinela. Caso contrário, talvez o código possa usar algo parecido (shell-command "texdoc --view listings &").
Stefan
É explicado nos comentários para TeX-documentation-texdoc: a ...-to-stringvariante é usada para mostrar aos usuários possíveis mensagens de erro (por exemplo, quando nenhuma documentação é encontrada). Além disso, texdoc nonexistingpackageretorna 0, mas o sentinela pode ser usado para analisar a saída.
Giordano
Então um sentinela parece ser a melhor opção.
23416 Stefan
Não consigo encontrar uma invocação start-file-processque realmente funcione aqui. (start-file-process "texdoc" "*texdoc*" "texdoc" "--view" "listings")cria o buffer *texdoc*no qual está inserido "Processo texdoc concluído" e o pdf nunca é aberto. O mesmo acontece quando eu configuro o visualizador de PDF do xdg-mime para evidenciar também.
Tyler
1

Se você precisar apenas enviar uma solicitação ao Emacs, sem aguardar uma resposta, poderá executar emacsclientem segundo plano. Em sistemas operacionais no estilo Unix (Linux, macOS, Cygwin,…):

emacsclient … &

No Windows nativo:

start emacsclient …
Gilles 'SO- parar de ser mau'
fonte
Claro, mas nesse caso em particular eu preciso chamar um programa (texdoc) que chama (emacsclient). O nível adicional de redirecionamento está causando problemas.
Tyler
@Tyler texdocé assíncrono (ou seja, você não está esperando a conclusão), não é? Portanto, você pode aplicar o mesmo princípio: execute texdoc … &como o comando shell.
Gilles 'SO- stop be evil'
Tentamos isso nos comentários da minha pergunta; funciona ao ligar emacsclientdiretamente, mas não ao ligar texdoc.
Tyler