Next: Decoding Output, Previous: Process Buffers, Up: Output from Processes [Contents][Index]
プロセスのフィルター関数(filter function)は、関連付けられたプロセスからの標準出力を受信します。そのプロセスのすべての出力はそのフィルターに渡されます。デフォルトのフィルターは単にプロセスバッファーに直接出力します。
デフォルトではプロセス用のエラー出力がもしあれば、プロセス作成時にプロセスの標準エラーストリームが標準出力から分離されていなければフィルター関数に渡されます。Emacsは特定の関数の呼び出し中のみフィルター関数を呼び出します。Output from Processesを参照してください。フィルターによりこれらの関数のいずれかが呼び出されると、フィルターが再帰的に呼び出されるかもしれないことに注意してください。
フィルター関数は関連付けられたプロセス、およびそのプロセスから正に受信した出力である文字列という2つの引数を受け取らなければなりません。関数はその後に出力にたいして何であれ自由に行うことができます。
quitは通常はフィルター関数内では抑制されます。さもないとコマンドレベルでのC-gのタイプ、またはユーザーコマンドのquitは予測できません。フィルター関数内部でのquitを許可したければinhibit-quit
をnil
にバインドしてください。ほとんどの場合において、これを行う正しい方法はマクロwith-local-quit
です。Quittingを参照してください。
フィルター関数の実行中にエラーが発生すると、フィルター開始時に実行中だったプログラムが何であれ実行を停止しないように自動的にcatchされます。しかしdebug-on-error
が非nil
ならエラーはcatchされません。これによりLispデバッガーを使用したフィルター関数のデバッグが可能になります。Debuggerを参照してください。
多くのフィルター関数は時折(または常に)、デフォルトフィルターの動作を真似てプロセスのバッファーにその出力を挿入します。そのようなフィルター関数は確実にカレントバッファーの保存と、(もし異なるなら)出力を挿入する前に正しいバッファーを選択して、その後に元のバッファーをリストアする必要があります。またそのバッファーがまだ生きているか、プロセスマーカーを更新しているか、そしていくつかのケースにおいてはポイントの値を更新しているかもチェックするべきです。以下はこれらを行う方法です:
(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
;; テキストを挿入してプロセスマーカーを進める
(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
(Window Pointを参照)にセットしたほうがよいでしょう。
フィルター関数の実行中には、Emacsが自動的にマッチデータの保存とリストアを行うことに注意してください。Match Dataを参照してください。
フィルターへの出力は任意のサイズのchunkで到着する可能性があります。同じ出力を連続して2回生成するプログラムは一度に200文字を1回のバッチで送信して、次に40文字を5回のバッチで送信するかもしれません。フィルターが特定のテキスト文字列をサブプロセスの出力から探す場合には、それらの文字列が2回以上のバッチ出力を横断するケースに留意して処理してください。これを行うには受信したテキストを一時的なバッファーに挿入してから検索するのが1つの方法です。
この関数はprocessにフィルター関数filterを与える。filterがnil
なら、そのプロセスにたいしてプロセスバッファーにプロセス出力を挿入するデフォルトフィルターを与える。
この関数はprocessのフィルター関数をリターンする。
そのプロセスの出力を複数のフィルターに渡す必要がある場合には、既存のフィルターに新たなフィルターを組み合わせるためにadd-function
を使用できる。Advising Functionsを参照のこと。
以下はフィルター関数の使用例:
(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 ")