Викличте emacsclient з програми, яку викликає Emacs


9

У мене виникла проблема з переглядом файлів документації у форматі PDF з AucTex. Я використовую pdf-toolsдля перегляду PDF-файлів зсередини Emacs, і я встановив emacsclient -nяк свій pdf-переглядач за замовчуванням (через xdg-mime на Debian Linux). Це працює чудово за більшості обставин, але порушує (Tex-documentation-texdoc ...)функцію Auctex ( C-c ?).

Я звузив проблему до одного рядка коду. Коли я намагаюся переглянути документацію для listingsпакета, TeX-documentation-texdocперетворює це на наступний сексп:

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

texdocу свою чергу закликає emacsclientфактично відкрити файл (виходячи з того, як я налаштував свій робочий стіл через xdg). Однак у цей момент Emacs зависає, і мені потрібно кинути ( C-g), щоб повернути контроль. Після цього жоден новий pdf не відкривається. Те ж саме відбувається, якщо я намагаюся викликати emacsclient безпосередньо:

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

Обидві команди працюють у командному рядку (тобто, emacsclient -n tmp.pdfі texdoc --view listings.

Моє запитання полягає в такому випадку, як мені викликати emacsclient зсередини Emacs? (і я знаю, що я міг би просто відкрити файл pdf find-file; це не варіант, оскільки мені потрібно викликати зовнішній процес (texdoc), щоб знайти файл, і цей процес потім викликає emacsclient).


Чому б просто texdoc -M --list listingsне знайти файл, а потім скористатися find-file?
Кварк

@suvayu Просто зручність. Іншою альтернативою є перехід на термінал для виклику, texdoc --viewа потім перемикання назад на Emacs, коли він відкриває файл. Але я думаю, що має бути спосіб зробити це за один крок від Emacs?
Тайлер

1
Чи можете (async-shell-command "emacsclient -n tmp.pdf")вирішити проблему?
Ім'я

1
@ Ім'я цікаво - (async-shell-command "emacsclient -n tmp.pdf")працює, але (async-shell-command "texdoc --view listings")ні. Тож це корисна підказка.
Тайлер

1
Чи C-u C-c ?працює? Спочатку відображається список документів, пов’язаних із пакетом, потім відкривається глядач (call-process "texdoc" nil 0 nil "--just-view" doc).
giordano

Відповіді:


5

Рішення полягає в запуску texdocасинхронного процесу.

Найкращий спосіб зробити це, мабуть, використовувати start-file-processзамість shell-command-to-string(що є зручною функцією для швидкого та брудного коду, коли доцільніше написати невеликий скрипт оболонки, ніж відповідний код Elisp, але в іншому випадку краще уникати мого досвіду).

Але це потребує значних змін у навколишньому коді, оскільки start-file-processвін не повертає вихідний процес безпосередньо, натомість він дозволяє вказати, у який буфер розмістити вихід, а потім вам доведеться використовувати set-process-sentinelфункцію зворотного виклику, яка отримує вихід з цього буфера і робить "все, що потрібно зробити з цим", коли команда закінчиться.


У конкретному випадку запуску texdocв AUCTeX я вважаю, що використання дозорного трохи надмірне, оскільки це не є основоположною особливістю (наприклад, це відкриття переглядача вихідного документа, і в цьому випадку ми використовуємо дозорний).
giordano

Я поняття не маю, чому використовувалася функція "-to-string", тому я не знаю, що робиться з результатами команди. Якщо цей вихід потрібен (як запропоновано використанням ...-to-string), то для рішення асинхронізації знадобиться або фільтр процесу, або довідковий процес. Якщо ні, то, можливо, код може використовувати щось подібне (shell-command "texdoc --view listings &").
Стефан

Це пояснюється в коментарях до TeX-documentation-texdoc: ...-to-stringваріант використовується для показу користувачам можливих повідомлень про помилки (наприклад, коли не знайдено жодної документації). Крім того, texdoc nonexistingpackageповертає 0, але дозорний може бути використаний для розбору результатів.
giordano

Тоді дозорний здається найкращим варіантом.
Стефан

Я не можу знайти виклик того, start-file-processщо насправді працює тут. (start-file-process "texdoc" "*texdoc*" "texdoc" "--view" "listings")створює буфер *texdoc*, до якого вставляється "Process texdoc готовий", і pdf ніколи не відкривається. Те ж саме відбувається, коли я встановив переглядач файлів xdg-mime pdf так само, щоб переконатися.
Тайлер

1

Якщо вам потрібно лише повернути запит на Emacs, не чекаючи відповіді, ви можете запустити emacsclientу фоновому режимі. Під операційними програмами в стилі Unix (Linux, macOS, Cygwin,…):

emacsclient … &

Під рідною Windows:

start emacsclient …

Звичайно, але в цьому конкретному випадку мені потрібно викликати програму (texdoc), яка потім дзвонить (emacsclient). Додатковий рівень перенаправлення викликає проблеми.
Тайлер

@Tyler texdocасинхронний (тобто ви не чекаєте його завершення), чи не так? Таким чином, ви можете застосувати той же принцип: запустити, texdoc … &як команду shell.
Жил "ТАК - перестань бути злим"

Ми це спробували в коментарях під моїм запитанням; він працює при emacsclientбезпосередньому дзвінку , але не при дзвінку texdoc.
Тайлер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.