Викличте 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.