Next: , Previous: Interactive Call, Up: Command Loop


21.4 Distinguish Interactive Calls

Sometimes a command should display additional visual feedback (such as an informative message in the echo area) for interactive calls only. There are three ways to do this. The recommended way to test whether the function was called using call-interactively is to give it an optional argument print-message and use the interactive spec to make it non-nil in interactive calls. Here's an example:

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

We use "p" because the numeric prefix argument is never nil. Defined in this way, the function does display the message when called from a keyboard macro.

The above method with the additional argument is usually best, because it allows callers to say “treat this call as interactive.” But you can also do the job in a simpler way by testing called-interactively-p.

— Function: called-interactively-p

This function returns t when the calling function was called using call-interactively.

If the containing function was called by Lisp evaluation (or with apply or funcall), then it was not called interactively.

Here's an example of using called-interactively-p:

     (defun foo ()
       (interactive)
       (when (called-interactively-p)
         (message "foo"))
       'haha)
           foo
     
     ;; Type M-x foo.
          -| foo
     
     (foo)
           haha

Here is another example that contrasts direct and indirect calls to called-interactively-p.

     (defun bar ()
       (interactive)
       (setq foobar (list (foo) (called-interactively-p))))
           bar
     
     ;; Type M-x bar.
     ;; This does not display a message.
     
     foobar
           (nil t)

If you want to treat commands run in keyboard macros just like calls from Lisp programs, test interactive-p instead of called-interactively-p.

— Function: interactive-p

This function returns t if the containing function (the one whose code includes the call to interactive-p) was called in direct response to user input. This means that it was called with the function call-interactively, and that a keyboard macro is not running, and that Emacs is not running in batch mode.