抱歉,我尝试了几次而且我无法构建简单的defmacro
- 任何人都可以帮助我:
所以,我想要定义宏,它将扩展为:
(define-key keymap "*" (lambda ()
(interactive)
(some-func "*")))
我尝试过类似的事情:
(defmacro wrap-and-define-key (keymap key func)
`(define-key ,keymap ,key (lambda () (interactive) (,func ,key))))
它适用于:
(wrap-and-define-key keymap key func)
但不适用于
(wrap-and-define-key keymap key 'func)
如何更改defmacro语句以使最后一个表单正常工作?谢谢!
答案 0 :(得分:2)
你不需要一个宏。
(defun wrap-and-define-key (keymap key func)
(define-key keymap key (lambda () (interactive) (funcall func key))))
(不要引用lambda表格。避免使用eval
。)
不确定为什么要这样,但无论如何,这应该按照你的要求做。
答案 1 :(得分:2)
您的宏不适用于第二个示例的原因是'func
作为带引号的参数传递,因为宏的参数不会自动计算。所以宏中的lambda扩展为:
(lambda () (interactive) ('func key))
但是,当以这种方式调用函数名时,你不能引用它。只有lambda或不带引号的符号才能显示为函数调用表达式中的第一项。如果您将宏更改为:
(defmacro wrap-and-define-key (keymap key func)
`(define-key ,keymap ,key (lambda () (interactive) (funcall ,func ,key))))
它会起作用。调用lambda时,'func
将被计算为普通的func符号并传递给funcall。然后funcall在函数命名空间中查找符号(Elisp是 Lisp-2 )并调用它。
正如另一个答案中所建议的那样,你可以通过一个功能完成这个任务。无论是否启用词法模式,此功能都将起作用:
(defun wrap-and-define-key (keymap key func)
(define-key keymap key `(lambda () (interactive) (funcall ',func ,key))))
答案 2 :(得分:0)
好的,找到一些有效但不确定的东西 - 这是一个优雅的解决方案:
(defmacro wrap-and-define-key (keymap key func)
`(define-key ,keymap ,key '(lambda () (interactive) (eval (list ,func ,key)))))