Next: , Previous: , Up: Command Loop   [Contents][Index]


20.4 interactiveな呼び出しの区別

interactive呼び出しの際に、コマンドが(エコーエリア内の情報メッセージなどのような)視覚的な追加フィードバックを表示すべきときがあります。これを行うためには3つの方法があります。その関数がcall-interactivelyを使用して呼び出されたかどうかテストするには、オプション引数print-messageを与えるとともに、interactive呼び出しで非nilとなるようにinteractive仕様を使うのが推奨される方法です。以下は例です:

(defun foo (&optional print-message)
  (interactive "p")
  (when print-message
    (message "foo")))

数プレフィクス引数は決してnilにならないので、わたしたちは"p"を使用します。この方法で定義された関数はキーボードマクロから呼び出されたときにメッセージを表示します。

追加引数による上記の手法は、呼び出し側に“この呼び出しをinteractiveとして扱うように”伝えることができるので通常は最善です。しかしcalled-interactively-pをテストすることによってこれを行うこともできます。

Function: called-interactively-p kind

この関数は呼び出された関数がcall-interactivelyを使用して呼び出されえいたらtをリターンする。

引数kindはシンボルinteractiveかシンボルanyのいずれかである。これがinteractiveなら、called-interactively-pはユーザーから直接呼び出しが行われたとき — たとえば関数呼び出しにバインドされたキーシーケンスをユーザーがタイプした場合がそれに該当するが、ユーザーがその関数を呼び出すキーボードマクロ(Keyboard Macrosを参照)を実行中した場合は該当しない — だけtをリターンする。kindanyなら、called-interactively-pはキーボードマクロを含む任意の種類のinteractive呼び出しにたいしてtをリターンする。

疑わしい場合にはanyを使用すること。interactiveの使用が正しいと解っているのは、関数が実行中に役に立つメッセージを表示するかどうか判断が必要な場合だけである。

Lisp評価(またはapplyfuncall))を通じて呼び出された場合には、関数は決してインタラクティブに呼び出されたとは判断されない。

以下はcalled-interactively-pを使用する例:

(defun foo ()
  (interactive)
  (when (called-interactively-p 'any)
    (message "Interactive!")
    'foo-called-interactively))

;; M-x fooとタイプする
     -| Interactive!

(foo)
     ⇒ nil

以下はcalled-interactively-pの直接呼び出しと間接呼び出しを比較した例。

(defun bar ()
  (interactive)
  (message "%s" (list (foo) (called-interactively-p 'any))))

;; M-x barとタイプする
     -| (nil t)