コマンドによっては、インタラクティブな呼び出し時のみ追加の視覚的フィードバック(エコー領域への情報メッセージなど)を表示させる必要がある場合があります。これを実現する方法は3通りあります。関数がcall-interactivelyを用いて呼び出されたかどうかを判定する推奨方法は、オプション引数print-messageを指定し、interactive仕様を用いてインタラクティブな呼び出し時にはnilにならないようにすることです。以下に例を示します:
(defun foo (&optional print-message)
(interactive "p")
(when print-message
(message "foo")))
数値プレフィックス引数が nil になることがないため、"p"
を使用しています。このように定義することで、キーボードマクロから呼び出された際に、関数がメッセージを表示するようになります。
追加引数を用いた上記の手法は、呼び出し側が「この呼び出しを対話的なものとして扱う」と指定できるため、通常は最適です。ただし、called-interactively-p を判定することでも同様の処理が可能です。
この関数は、呼び出し元の関数が call-interactively を用いて呼び出された場合に
t を返します。
引数 kind は、シンボル interactive
またはシンボル any のいずれかである必要があります。interactive の場合、called-interactively-p が t
を返すのは、ユーザーによって直接呼び出された場合に限られます(例えば、ユーザーが呼び出し関数にバインドされたキーシーケンスを入力した場合などです。ただし、ユーザーがその関数を呼び出すキーボードマクロを実行した場合は除きます(キーボードマクロを参照)。kind が
any の場合、called-interactively-p はキーボードマクロを含むあらゆる種類の対話的な呼び出しに対して
t を返します。
迷った場合は any を使用してください。interactive
の唯一知られている適切な用途は、関数の実行中にヘルプメッセージを表示するかどうかを判断する必要がある場合です。
Lispによる評価(または apply や funcall による呼び出し)を介して呼び出された関数は、インタラクティブに呼び出されたとはみなされない。
called-interactively-p の使用例を以下に示します。
(defun foo ()
(interactive)
(when (called-interactively-p 'any)
(message "Interactive!")
'foo-called-interactively))
;; Type M-x foo.
⊣ Interactive!
(foo)
⇒ nil
called-interactively-pへの直接呼び出しと間接呼び出しを対比させた別の例を以下に示します。
(defun bar () (interactive) (message "%s" (list (foo) (called-interactively-p 'any))))
;; Type M-x bar.
⊣ (nil t)