[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

20.11 再帰編集

Emacsが動作を始めると、Emacsのコマンドループに自動的に入ります。 このトップレベルのコマンドループからはけっして抜けることはなく、 Emacsが動いている限り動作し続けます。 Lispプログラムからコマンドループを起動することもできます。 そうすると、活性なコマンドループが複数作られることになるので、 それを再帰編集(recursive editing)と呼びます。 再帰編集レベルには、それを起動したコマンドを一時休止させ、 当該コマンドを再開するまでユーザーにどんな編集でも許す効果があります。

再帰編集中に利用可能なコマンドは、トップレベルのコマンドループと 同じものでありキーマップで定義されます。 再帰編集を抜けるための数個の特別なコマンドがあり、 完了すると再帰編集レベルから抜ける別のコマンドもあります。 (再帰編集を抜けるコマンドはつねに利用可能であるが、 再帰編集中でないとなにも行わない。)

再帰編集を含むすべてのコマンドループでは、 コマンドループから実行したコマンドのエラーによって コマンドループから抜け出さないように汎用目的のエラーハンドラを設定します。

ミニバッファでの入力は、特別な種類の再帰編集です。 これには、ミニバッファやミニバッファ用ウィンドウを表示するなどの特別な 処理がありますが、読者が考えるよりは少ないのです。 ミニバッファでは特別なふるまいをするキーもありますが、 それらはミニバッファのローカルマップによるものです。 ウィンドウを切り替えると、Emacsの普通のコマンドを使えます。

再帰編集レベルを起動するには、関数recursive-editを呼び出します。 この関数にはコマンドループが含まれています。 さらに、exitを伴ったcatchの呼び出しもあり、 これにより、exitへ投げることで 再帰編集レベルから抜け出せるようになっています (see section 9.5.1 明示的な非ローカル脱出: catchthrow)。 t以外の値を投げると、recursive-editは、 呼び出し側の関数へ普通に戻ります。 コマンドC-M-cexit-recursive-edit)は、これを行います。 値tを投げるとrecursive-editに中断を引き起こし、 1つ上のレベルのコマンドループへ制御を戻します。 これを強制終了(aborting)と呼び、 C-]abort-recursive-edit)で行えます。

ミニバッファを使う場合を除いて、ほとんどのアプリケーションでは 再帰編集を使うべきではありません。 カレントバッファのメジャーモードを 一時的な特別なメジャーモードに変更するほうが、 一般にはユーザーにとってより便利です。 ただし、当該メジャーモードには、 まえのモードに戻るコマンドを用意しておきます。 (rmailのコマンドeは、この方式を使っている。) あるいは、『再帰的に』編集する別のテキストをユーザーに与えたい場合には、 特別なモードの新たなバッファを作成してそれを選択します。 当該モードには、処理を終えてまえのバッファに戻るコマンドを 定義しておきます。 (rmailのコマンドmは、このようにする。)

再帰編集はデバッグに便利です。 ブレークポイントの一種として関数定義に debugの呼び出しを挿入しておくと、 その箇所に達したときにいろいろと調べられます。 debugは再帰編集を起動しますが、デバッガとしての機能も提供します。

query-replaceC-rを打ったり、 C-x qkbd-macro-query)を使ったときにも 再帰編集レベルが使われます。

Function: recursive-edit
この関数はエディタコマンドループを起動する。 Emacsの初期化過程で自動的に呼び出され、ユーザーが編集できるようにする。 Lispプログラムから呼ばれると、再帰編集レベルに入る。

以下の例では、関数simple-recは、まず1単語分ポイントを進め、 エコー領域にメッセージを表示して再帰編集に入る。 そうすると、ユーザーは望むことはなんでもできるようになり、 (再帰編集を)抜けるためにC-M-cを打つと、 simple-recの実行を継続する。

 
(defun simple-rec ()
  (forward-word 1)
  (message "Recursive edit in progress")
  (recursive-edit)
  (forward-word 1))
     => simple-rec
(simple-rec)
     => nil

コマンド: exit-recursive-edit
この関数は、(ミニバッファでの入力を含む)もっとも内側の再帰編集から抜ける。 その関数定義は実質的には(throw 'exit nil)である。

コマンド: abort-recursive-edit
この関数は、再帰編集から抜けたあとでquitを通知することで、 (ミニバッファでの入力を含む)もっとも内側の再帰編集を 要請したコマンドを強制終了する。 その関数定義は実質的には(throw 'exit t)である。 see section 20.9 中断

コマンド: top-level
この関数は、すべての再帰編集を抜ける。 すべての計算を抜け出てメインのコマンドループへ直接戻るため、値は返さない。

Function: recursion-depth
この関数は再帰編集の現在の深さを返す。 活性な再帰編集がなければ0を返す。



This document was generated by Takeshi Sasaoka on , 21 2002 using texi2html