Next: , Previous: , Up: Output from Processes   [Contents][Index]


38.9.2 プロセスのフィルター関数

プロセスのフィルター関数(filter function)は、関連付けられたプロセスからの標準出力を受信します。そのプロセスのすべての出力はそのフィルターに渡されます。デフォルトのフィルターは単にプロセスバッファーに直接出力します。

デフォルトではプロセス作成時にエラーストリームの出力先が標準出力と分離されていなければ(Output from Processesを参照)、プロセスからのエラー出力があればそれはフィルター関数にも渡されます。

サブプロセスからの出力はEmacsが何かを待機している間だけ到着するので、フィルター関数はそのようなときだけ呼び出し可能です。Emacsは端末入力読み取り時(関数waiting-for-user-input-pWaitingsit-forsleep-for、およびAccepting Outputaccept-process-outputを参照)に待機します。

フィルター関数は関連付けられたプロセス、およびそのプロセスから正に受信した出力である文字列という2つの引数を受け取らなければなりません。関数はその後に出力にたいして何であれ自由に行うことができます。

quitは通常はフィルター関数内では抑制されます。さもないとコマンドレベルでのC-gのタイプ、またはユーザーコマンドのquitは予測できません。フィルター関数内部でのquitを許可したければinhibit-quitnilにバインドしてください。ほとんどの場合において、これを行う正しい方法はマクロ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を呼び出してください。

フィルター関数の実行中には、Emacsが自動的にマッチデータの保存とリストアを行うことに注意してください。Match Dataを参照してください。

フィルターへの出力は任意のサイズのchunkで到着する可能性があります。同じ出力を連続して2回生成するプログラムは一度に200文字を1回のバッチで送信して、次に40文字を5回のバッチで送信するかもしれません。フィルターが特定のテキスト文字列をサブプロセスの出力から探す場合には、それらの文字列が2回以上のバッチ出力を横断するケースに留意して処理してください。これを行うには受信したテキストを一時的なバッファーに挿入してから検索するのが1つの方法です。

Function: set-process-filter process filter

この関数はprocessにフィルター関数filterを与える。filternilなら、そのプロセスにたいしてプロセスバッファーにプロセス出力を挿入するデフォルトフィルターを与える。

Function: process-filter process

この関数は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
")