我正在尝试创建类似于with-eval-after-load
的内容,除了在提供所有功能之后,主体会进行评估。此外,必须在运行时提供功能列表。
例如,我想要类似的东西
(setq feature-list '(a b))
(something feature-list (message "a and b both provided"))
其功能等同于
(with-eval-after-load 'a
(with-eval-after-load 'b
(message "a and b both provided")))
在运行时提供列表似乎是棘手的部分。没有这个要求,我可以写一个宏:
(defmacro eval-after-load-all (features body)
(if (null features)
body
`(with-eval-after-load (quote ,(car features))
(eval-after-load-all ,(cdr features) ,body))))
并通过以下方式传递列表:
(eval-after-load-all (a b) (message "a and b both provided"))
但是将其传递给feature-list
会使它使用文字字符“功能列表”。
我尝试定义一个递归函数:
(defun eval-after-load-all (features body)
(if (null features)
body
(with-eval-after-load (car features)
(eval-after-load-all (cdr features) body))))
但是当我评估
(eval-after-load-all feature-list (message "a and b both provided"))
(provide 'a)
;; (provide 'b)
它在(provide 'a)
调用中触发错误,并在递归调用步骤(即函数中的最后一个表达式)抱怨void-variable body
。这个范围使我感到困惑。为什么body
在这里无效?
我还尝试将宏包装在函数中,以便可以向其传递评估后的参数:
(defun macro-wrapper (features body)
(eval-after-load-all features body))
但是这在函数定义中抱怨features
不是列表:wrong-type-argument listp features
。
答案 0 :(得分:0)
features
作为自变量,因为那是(我引用features
的文档):
符号列表,它们是正在执行的Emacs的功能。 由
featurep
和require
使用,并由provide
更改。
eval-after-load-all
的代码可以正常工作。它是从您的递归函数定义派生的。funcall
或eval
的形式将函数的形式或表达式的形式添加了评估,对lambda使用了反引号,并在生成的lambda中引入了对列表和表达式的引用表达。(defun eval-after-load-all (my-features form)
"Run FORM after all MY-FEATURES are loaded.
See `eval-after-load' for the possible formats of FORM."
(if (null my-features)
(if (functionp form)
(funcall form)
(eval form))
(eval-after-load (car my-features)
`(lambda ()
(eval-after-load-all
(quote ,(cdr my-features))
(quote ,form))))))