核心是功能和命令之间存在差异。
在Emacs lisp中,默认情况下不能交互调用函数。这意味着您无法通过访问它们M-x
或将它们绑定到按键或鼠标单击。如果要这样做,则需要将函数显式声明为,方法是在主体的第一行中interactive
添加一个(interactive)
表单(紧随文档字符串之后)。交互式功能称为命令。在手册中对此进行了说明:((info "(elisp) Using Interactive")
在线版本)。
您看到的错误消息Wrong type argument: commandp, my-function
表示您正在尝试以交互方式调用一个函数,但该函数不是command。
为了解释实际错误,该字母p
经常用大写字母表示指示谓词或测试。在这种情况下,Emacs正在测试my-function
以查看它是否是使用test的命令commandp
。不是,这会导致错误。每当使用错误类型的对象时,都会弹出类似的错误:例如,如果Emacs需要一个字符串并传递一个符号,则可能会看到对的引用stringp
。
要按要求回答问题,您需要(interactive)
在定义中添加以下行:
(defun my-function ()
(interactive)
(message "This is a great function"))
表单有很多选项interactive
,支持将信息传递到函数的各种方式。查看手册以获取所有详细信息。
在这种情况下,键盘宏是一种特殊情况。键盘宏是一系列输入事件,用字符串表示。键盘宏的行为类似于命令,因此您可以将它们绑定到键,而不必担心添加interactive
声明。例如,在以下内容中:
(global-set-key (kbd "C-c l") "λ")
"λ"
是键盘宏,因此我们可以C-c l
毫无问题地将其绑定到。如果我们尝试对函数执行相同的操作,则必须确保将函数定义为interactive
:
(global-set-key (kbd "C-c k")
(lambda () (insert "λ"))
;; C-c k is undefined! We tried to bind it to a function
(global-set-key (kbd "C-c m")
(lambda () (interactive) (insert "λ"))
;; C-c m is bound to a command that inserts λ