Next: Prefix Command Arguments, Previous: Waiting, Up: Command Loop [Contents][Index]
Lisp関数を実行中にC-gをタイプすると、Emacsが何を行っていてもEmacsをquit(中止、終了)させます。これはアクティブなコマンドループの再内に制御がリターンすることを意味します。
コマンドループがキーボード入力待機中にC-gをタイプしてもquitはしません。これは通常の入力文字として機能します。もっともシンプルなケースでは、通常C-gはquitの効果をもつkeyboard-quit
を実行するので、区別できませんしかしプレフィクスキーの後のC-gは、未定義のキー組み合わせになります。これはプレフィクスキーやプレフィクスキーも同様にキャンセルする効果をもちます。
ミニバッファー内では、C-gは異なる定義をもち、それはミニバッファーをabort(失敗、中止、中断)します。これは実際にはミニバッファーをexitしてquitします(単にquitするのはミニバッファー内のコマンドループにリターンするだろう)。C-gがなぜコマンドリーダーが入力読み取り時に直接quitしないかという理由は、ミニバッファー内でC-gの意味をこの方法により再定義可能にするためです。プレフィクスキーの後のC-gはミニバッファー内で再定義されておらず、プレフィクスキーおよびプレフィクス引数のキャンセルという通常の効果をもちます。もしC-ggヴぁ常に直接quitするなら、これは不可能でしょう。
C-gが直接quitを行うときは、変数quit-flag
をt
にセットすることによりそれを行います。Emacsは適切なときにこの変数をチェックして、nil
でない場合はquitします。どのような方法でも、quit-flag
を非nil
にセットするとquitが発生します。
Cコードのレベルでは、どこでもquitを発生させることはできず、quit-flag
をチェックする特別な場所でのみquitが発生します。この理由は、他の場所でquitすると、Emacsの内部状態が矛盾が生じるかもしれないからです。安全な場所までquitが遅延されるので、quitがEmacsをクラッシュさせることがなくなります。
read-key-sequence
やread-quoted-char
のような特定の関数は、たとえ入力を待機中でもquitを抑制します。quitするかわりに、C-gは要求された入力として処理されます。read-key-sequence
の場合、これはコマンドループ内でのC-gの特別な振る舞いを引き起こすのに役立ちます。read-quoted-char
の場合、これはC-gをクォートするのにC-qを使用できるようにします。
変数inhibit-quit
を非nil
値にバインドすることにより、Lisp関数の一部でquitを抑止できます。その場合は、quit-flag
をt
にセットされていても、C-gの通常の結果であるquitは抑止されます。let
フォームの最後でこのバインディングがunwindされるなどして、結果としてinhibit-quit
は再びnil
になります。このときquit-flag
がnil
の場合には、即座に要求されたquitが発生します。この挙動は、プログラム中の“クリティカルセクション”内でquitが発生しないことを確実にしたいときに理想的です。
(read-quoted-char
のような)いくつかの関数では、quitを起こさない特別な方法でC-gが処理されます。これはinhibit-quit
をt
にバインドして入力を読み取り、再びinhibit-quit
がnil
になる前にquit-flag
をnil
にセットすることにより行われます。以下は、これを行う方法を示すためのread-quoted-char
の抜粋です。この例は入力の最初の文字の後で通常のquitを許す方法も示しています。
(defun read-quoted-char (&optional prompt)
"…documentation…"
(let ((message-log-max nil) done (first t) (code 0) char)
(while (not done)
(let ((inhibit-quit first)
…)
(and prompt (message "%s-" prompt))
(setq char (read-event))
(if inhibit-quit (setq quit-flag nil)))
… 変数code
をセット …)
code))
この変数が非nil
でinhibit-quit
がnil
の場合、macsは即座にquitする。C-gをタイプすると、通常はinhibit-quit
とは無関係にquit-flag
を非nil
にセットする。
この変数は、quit-flag
が非nil
にセットされているときEmacsがquitするかどうかを決定する。inhibit-quit
が非nil
の場合、quit-flag
は特に効果がない。
このマクロはbodyを順番に実行するが、たとえこの構成の外部でinhibit-quit
が非nil
でも、少なくともローカルにbody内でのquitを許す。このマクロはquitによりexitした場合はnil
、それ以外はbody内の最後のフォームの値をリターンする。
inhibit-quit
がnil
の場合with-local-quit
へのエントリーでbodyだけが実行され、quit-flag
をセットすることにより通常のquitが発生する。しかし通常のquitが遅延されるようにinhibit-quit
が非nil
にセットされている場合、非nil
のquit-flag
は特別な種類のローカルquitを引き起こす。これはbodyの実行を終了して、quit-flag
を非nil
のままでwith-local-quit
ボディーをexitするので、許され次第(通常の)他のquitが発生する。bodyの先頭ですでにquit-flag
が非nil
の場合、即座にローカルquitが発生して結局ボディーは実行されない。
このマクロは主にタイマー、プロセスフィルター、プロセスセンチネル、pre-command-hook
、post-command-hook
、およびinhibit-quit
が通常はt
にバイドされている場所で役に立つ。
この関数は(signal 'quit
nil)
によりquit
条件をシグナルする。これはquitが行うことと同じである(Errorsのsignal
を参照)。
quitに使用するC-g以外の文字を指定できます。Input Modes内の関数set-input-mode
を参照してください。