Прежде всего, отказ от ответственности. Я исследовал это много раз, и я почти уверен, что я уже нашел ответ, так или иначе, но я просто не понимаю его.
Моя проблема заключается в следующем:
- У меня процесс проходит через коминт
- Я хочу отправить строку ввода, захватить вывод и посмотреть, когда он закончится (когда последняя строка вывода соответствует регулярному выражению для приглашения)
- только когда процесс завершит отправку вывода, я хочу отправить еще одну строку ввода (например).
Для некоторой предыстории подумайте о основном режиме, реализующем взаимодействие с программой, которое может возвращать произвольное количество выходных данных в произвольно долгое время. Это не должно быть необычной ситуацией, верно? Хорошо, возможно, часть, где мне нужно ждать между входами, необычна, но у нее есть несколько преимуществ по сравнению с отправкой ввода в целом:
- выходной буфер красиво отформатирован: ввод-вывод-вывод-вывод ...
- что еще более важно, при отправке большого количества текста процессу, текст разрезается на части, а части вставляются процессом обратно; точки обрезки являются произвольными, и это иногда приводит к неправильному вводу (мой процесс, например, не будет правильно вставлять вырезку ввода в середине идентификатора)
Во всяком случае, необычный или нет, то получается, что это будет сложно. Прямо сейчас я использую что-то вроде
(defun mymode--wait-for-output ()
(let ((buffer (mymode-get-buffer)))
(with-current-buffer buffer
(goto-char (point-max))
(forward-line 0)
(while (not (mymode-looking-at-prompt))
(accept-process-output nil 0.001)
(redisplay)
(goto-char (point-max))
(forward-line 0))
(end-of-line))))
и я вызываю это каждый раз после отправки строки ввода и перед отправкой следующей. Ну ... это работает, это уже что-то.
Но это также приводит к зависанию emacs в ожидании вывода. Причина очевидна, и я подумал, что если бы я включил sleep-for
в цикл какой-то асинхронный (например, 1 с), он бы задержал вывод на 1 с, но подавил зависание. За исключением того, что кажется, что такого рода асинхронный
sleep-for
не существует .
Или это? В более общем смысле, есть ли идиоматический способ добиться этого с помощью emacs? Другими словами:
Как отправить входные данные процессу, дождаться вывода, а затем отправить дополнительные входные данные асинхронно?
При поиске (см. Связанные вопросы) я в основном видел упоминания о дозорных (но я не думаю, что это применимо в моем случае, так как процесс не завершается) и о некоторых ловушках для коминтов (но что тогда? сделайте ловушку буферной локальной, превратите мою «оценку оставшихся строк» в функцию, добавьте эту функцию в ловушку и затем очистите ловушку - это звучит очень грязно, не так ли?).
Мне жаль, если я не проясняю себя, или если где-то есть действительно очевидный ответ, меня действительно смущают все сложности взаимодействия процессов.
При необходимости я могу сделать все это рабочим примером, но я боюсь, что это просто сделает еще один «конкретный вопрос процесса с конкретным ответом процесса», как все те, что я нашел ранее и не помог мне.
Некоторые связанные вопросы по SO: