次: Accepting Output, 前: Process Buffers, 上: Output from Processes
プロセスのフィルタ関数(filter function)は、 対応付けられたプロセスからの標準出力を受け取る関数です。 プロセスにフィルタがあると、そのプロセスからのすべての出力は フィルタに渡されます。 プロセスにフィルタがない場合に限って、 プロセスからの出力向けにプロセスバッファを直接使います。
フィルタ関数は、Emacsがなにかを待っているときにのみ呼ばれます。
そのような期間にのみプロセスの出力が到着するからです。
Emacsが待つのは、端末入力を読んでいるとき、
sit-for
やsleep-for
を実行中のとき(see Waiting)、
accept-process-output
(see Accepting Output)を実行中のときです。
フィルタ関数は2つの引数、 対応付けられたプロセスとそのプロセスから受け取ったばかりの出力である文字列を 受け取ります。 関数は出力に対してなにを行ってもかまいません。
フィルタ関数の内側では中断は普通は禁止されています。
さもないと、コマンドレベルで打ったC-gの効果や、
ユーザーコマンドを中断するために打ったC-gの効果は予測できません。
フィルタ関数の内側で中断を行いたい場合には、
inhibit-quit
にnil
を束縛します。
See Quitting。
フィルタ関数の実行中にエラーが発生するとそのエラーは自動的に捕捉され、
フィルタ関数を始動したときに動いていた
プログラムの実行を停止しないようにします。
しかし、debug-on-error
がnil
以外であると、
エラーを捕捉しません。
これにより、Lispデバッガでフィルタ関数をデバッグできます。
See Debugger。
多くのフィルタ関数は、ときどきあるいはつねに、
プロセスのバッファにテキストを挿入します。
これはフィルタ関数がないときのEmacsの動作を模倣するものです。
そのようなフィルタ関数では、対象のバッファに挿入するために
set-buffer
を使う必要があります。
カレントバッファをなかば恒久的に切り替えないように、
これらのフィルタ関数はカレントバッファを記録/復元する必要があります。
プロセスマーカを更新し、必要に応じてポイントの値も更新します。
これらはつぎのように行います。
(defun ordinary-insertion-filter (proc string)
(with-current-buffer (process-buffer proc)
(let ((moving (= (point) (process-mark proc))))
(save-excursion
;; テキストを挿入し、プロセスマーカを進める
(goto-char (process-mark proc))
(insert string)
(set-marker (process-mark proc) (point)))
(if moving (goto-char (process-mark proc))))))
カレントバッファを記録/復元するためにsave-excursion
ではなく
with-current-buffer
を使うのは、
2番目のgoto-char
の呼び出しで行うポイントの移動効果を
有効にするためです。
新たにテキストが到着するたびにプロセスバッファが見えるように
フィルタ関数で強制するには、
つぎのような行をwith-current-buffer
の直前に入れます。
(display-buffer (process-buffer proc))
ポイント位置に関わらずに新たな出力の末尾にポイントを移動するには、
変数moving
を削除して、
無条件にgoto-char
を呼び出します。
Emacsの初期の版では、正規表現を探索したり一致処理するフィルタ関数では、 マッチデータを明示的に保存/復元する必要がありました。 今のEmacsは、フィルタ関数に対してはこれを自動的に行いますから、 フィルタ関数で明示的に行う必要はありません。 See Match Data。
プロセスのバッファに出力を書き込むフィルタ関数は、
そのバッファが有効であるかどうかを検査するべきです。
無効なバッファに挿入しようとするとエラーになります。
バッファが無効であれば、
式(buffer-name (process-buffer
process))
を実行するとnil
を返します。
関数に渡される出力は任意のサイズの塊できます。 同じ出力を2回生成するプログラムは、 あるときには一度に200文字の塊を1つ送る場合もあれば、 40文字の塊を5つ送る場合もあります。 サブプロセスの出力から特定のテキスト文字列を探すフィルタでは、 そのような文字列が2つかそれ以上の出力の塊に分割される場合も 扱えるようにします。
この関数は、プロセスprocessにフィルタ関数filterを指定する。 filterが
nil
であると、プロセスにフィルタはない。
フィルタ関数の使用例をつぎに示します。
(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[8] % " "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 ")