Иногда команда должна отображать дополнительную визуальную обратную связь (например, информационное сообщение в области эхо) только для интерактивных вызовов. Существует три способа сделать это. Рекомендуемый способ проверки того, был ли вызов выполнен с использованием call-interactively, — это передать ему необязательный аргумент print-message и использовать спецификатор interactive, чтобы он не был nil в интерактивных вызовах. Вот пример:
(defun foo (&optional print-message)
(interactive "p")
(when print-message
(message "foo")))
Мы используем "p", потому что аргумент числового префикса никогда не бывает nil. Определенная таким образом, функция отображает сообщение при вызове из макроса клавиатуры.
Вышеупомянутый метод с дополнительным аргументом обычно лучше, потому что он позволяет вызывающим функциям сказать: «обращаться с этим вызовом как с интерактивным». Но вы также можете выполнить эту задачу, проверяя called-interactively-p.
Эта функция возвращает t, если вызывающая функция была вызвана с использованием call-interactively.
Аргумент 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))
;; Введите 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)