Spec-Zone.ru › Elisp

Функции-фильтры процессов

Функция-фильтр процесса — это функция, получающая стандартный вывод связанного с ней процесса. Весь вывод этого процесса передаётся фильтру. Фильтр по умолчанию просто напрямую выводит данные в буфер процесса.

По умолчанию вывод ошибок процесса, если он есть, также передаётся функции-фильтру, кроме случаев, когда при создании процесса поток стандартного вывода ошибок был отделён от стандартного потока вывода. 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API