The way you define a function is important when this function has to be called by command-execute
what would be the case if this function is invoked by a user pressing a keyboard key.
When invoked directly from within elisp code the function can run as you have specified it, but to avoid the error message you have experienced you need to mark the function as interactive by using the directive (interactive)
as first statement after the documentation string in the function definition. .
For more details, see 3.3 Make a Function Interactive or visit the Info node in Emacs with M-:(info "(eintr) Interactive")
and the answer to the question "Why can't I bind my function to a key or call it with M-x?".
By the way, knowing how it comes that the error is raised you can "fool" the detection mechanism of an actual interactive call and simulate it from elisp code by running this function using command-execute
.
Run the code below to see that the function will report that it was called interactively when actually called from elisp script and not by user pressing a key:
(defun interactive-aware-fun ()
"This function can detect if it was called from script or invoked by
a keypress using 'called-interactively-p' "
(interactive); required, else if called by a keypress there will be
; ^ an error message: command-execute : Wrong type argument: commandp, interactive-aware-fun
(message "interactive-aware-fun called-interactively-p : %s" (called-interactively-p))
)
(interactive-aware-fun) ;; gives nil
(global-set-key (kbd "<f9>") 'interactive-aware-fun) ;; [F9] gives t
(command-execute 'interactive-aware-fun) ;; gives t
(interactive)
before the(message ...)
inside the function namedinteractive-aware-fun
?command-execute
, so the first thing to do isC-h f command-execute
. E.g. try(command-execute 'interactive-aware-fun
)`.