我在自己的配置里用general.el绑定按键,因此引发了一个不是问题的问题:
我在general的配置里定义了一些definer用来绑定按键,并在其他的配置文件里使用他们,这样一来我就必须确保这些definer在其他配置运行的时候已经定义了。
我还还不能用(with-eval-after-load 'general ...)
,因为definer的定义就是这么配置的,没法保证definer的定义最先运行。
我完全可以直接加载general并且把它放在最开始加载以解决依赖问题,但是这么搞感觉很易碎。
我想到的办法是照抄一个provide
和eval-after-load
:(provide 'feature)
的时候,如果有挂载的钩子,运行钩子。(with-eval-after-load 'feature hook)
加载钩子的时候,如果feature
已经加载了,直接运行钩子,如果没有,把钩子挂载到feature下。
又解决一个强迫症,可喜可贺。
有没有人遇到同样的问题?怎么解决的?
P.S. 我记得spacemacs和doom也有类似问题的系统,但是具体什么样已经忘了。
(defvar luna--feature-hook-alist nil
"Stores hooks for each feature declared by ‘luna-provide’.
Each element is like (feature . (hooks ...)).")
(defvar luna--feature-enable-alist nil
"Stores whether a particular feature is provided already.")
(defun luna-provide (feature)
"Provide FEATURE."
(let ((hook-list (alist-get feature luna--feature-hook-alist)))
(when hook-list
;; something is already appended to hook
(mapc #'funcall hook-list))
(setf (alist-get feature luna--feature-enable-alist)
t)))
(defun luna-eval-after-load (feature hook)
"Ensure FEATURE (a symbol) is provided before running HOOK.
HOOK is a function."
(if (alist-get feature luna--feature-enable-alist)
;; feature already provided
(funcall hook)
(setf (alist-get feature luna--feature-hook-alist)
(append (alist-get feature luna--feature-hook-alist)
(list hook)))))
(defmacro luna-with-eval-after-load (feature &rest body)
"Ensure FEATURE (a symbol) is provided before evaluating BODY.
HOOK is a function."
(declare (indent 1))
`(luna-eval-after-load ,feature (lambda () ,@body)))