Функции-фильтры процессов
Функция-фильтр процесса — это функция, получающая стандартный вывод связанного с ней процесса. Весь вывод этого процесса передаётся фильтру. Фильтр по умолчанию просто напрямую выводит данные в буфер процесса.
По умолчанию вывод ошибок процесса, если он есть, также передаётся функции-фильтру, кроме случаев, когда при создании процесса поток стандартного вывода ошибок был отделён от стандартного потока вывода. Emacs вызывает функцию-фильтр только во время выполнения определённых функций. См. Получение вывода от процессов. Обратите внимание: если какая-либо из этих функций вызывается фильтром, фильтр может быть вызван рекурсивно.
Функция-фильтр должна принимать два аргумента: связанный процесс и строку, которая содержит только что полученный от него вывод. Затем функция может делать с этим выводом всё, что сочтёт нужным.
Выполнение команды выхода обычно блокируется внутри функции-фильтра — иначе результат нажатия C-g на уровне команд или выхода из пользовательской команды был бы непредсказуемым. Если вы хотите разрешить выход внутри функции-фильтра, привяжите inhibit-quit к nil. В большинстве случаев правильнее всего сделать это с помощью макроса with-local-quit. См. Выход.
Если во время выполнения функции-фильтра возникает ошибка, она перехватывается автоматически, чтобы не прерывать выполнение программы, работавшей в момент запуска функции-фильтра. Однако если debug-on-error не равно nil, ошибки не перехватываются. Это позволяет использовать отладчик Lisp для отладки функций-фильтров. См. Отладчик Lisp. Если ошибка перехвачена, Emacs приостанавливается на process-error-pause-time секунд, чтобы пользователь увидел её. См. Создание асинхронного процесса.
Многие функции-фильтры иногда (или всегда) вставляют вывод в буфер процесса, имитируя действия фильтра по умолчанию. Такие функции-фильтры должны сохранять текущий буфер, выбирать нужный буфер (если он отличается от текущего) перед вставкой вывода, а затем восстанавливать исходный буфер. Кроме того, им следует проверять, существует ли ещё буфер, обновлять маркер процесса, а в некоторых случаях — и значение точки. Вот как это сделать:
(defun ordinary-insertion-filter (proc string)
(when (buffer-live-p (process-buffer proc))
(with-current-buffer (process-buffer proc)
(let ((moving (= (point) (process-mark proc))))
(save-excursion
;; Insert the text, advancing the process marker.
(goto-char (process-mark proc))
(insert string)
(set-marker (process-mark proc) (point)))
(if moving (goto-char (process-mark proc)))))))
Чтобы фильтр обеспечивал видимость буфера процесса при поступлении нового текста, можно вставить следующую строку непосредственно перед конструкцией with-current-buffer:
(display-buffer (process-buffer proc))
Чтобы переместить точку в конец нового вывода независимо от её прежнего положения, удалите из примера переменную moving и безусловно вызовите goto-char. Обратите внимание, что это не обязательно перемещает точку окна. В фильтре по умолчанию используется insert-before-markers, которая перемещает все маркеры, включая точку окна. Это может переместить посторонние маркеры, поэтому обычно лучше перемещать точку окна явно или установить для неё тип вставки t (см. Окна и точка).
Обратите внимание, что Emacs автоматически сохраняет и восстанавливает данные о совпадениях во время выполнения функций-фильтров. См. Данные о совпадениях.
Вывод фильтру может поступать фрагментами любого размера. Программа, дважды подряд выдающая один и тот же вывод, в одном случае может отправить его одним пакетом из 200 символов, а в другом — пятью пакетами по 40 символов. Если фильтр ищет в выводе подпроцесса определённые строки текста, предусмотрите случай, когда одна из этих строк разбита на два или более фрагмента вывода; например, полученный текст можно вставить во временный буфер, в котором затем выполнить поиск.
- Функция: set-process-filter process filter
Эта функция назначает процессу process функцию-фильтр filter. Если filter равен
nil, процессу назначается фильтр по умолчанию, который вставляет вывод процесса в его буфер. Если filter равенt, Emacs прекращает принимать вывод процесса, за исключением сетевого серверного процесса, который ожидает входящих соединений.
- Функция: process-filter process
Эта функция возвращает функцию-фильтр процесса process.
Если вывод процесса необходимо передать нескольким фильтрам, можно использовать add-function, чтобы объединить существующий фильтр с новым. См. Адаптация функций Emacs Lisp.
Вот пример использования функции-фильтра:
(defun keep-output (process output)
(setq kept (cons output kept)))
⇒ keep-output
(setq kept nil)
⇒ nil
(set-process-filter (get-process "shell") 'keep-output)
⇒ keep-output
(process-send-string "shell" "ls ~/other\n")
⇒ nil
kept
⇒ ("lewis@slug:$ "
"FINAL-W87-SHORT.MSS backup.otl kolstad.mss~ address.txt backup.psf kolstad.psf backup.bib~ david.mss resume-Dec-86.mss~ backup.err david.psf resume-Dec.psf backup.mss dland syllabus.mss " "#backups.mss# backup.mss~ kolstad.mss ")
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Filter-Functions.html