解决配置内部的依赖问题


#1

我在自己的配置里用general.el绑定按键,因此引发了一个不是问题的问题:

我在general的配置里定义了一些definer用来绑定按键,并在其他的配置文件里使用他们,这样一来我就必须确保这些definer在其他配置运行的时候已经定义了。

我还还不能用(with-eval-after-load 'general ...),因为definer的定义就是这么配置的,没法保证definer的定义最先运行。

我完全可以直接加载general并且把它放在最开始加载以解决依赖问题,但是这么搞感觉很易碎。

我想到的办法是照抄一个provideeval-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)))

#2

general-create-definer 定义的是宏,只要 byte compile 了不就都不用先加載了。


我以前闲得蛋疼设计了个沒全部 byte-compile 就不能起动的配置。要手动 load 个正常不会加載的 el file 才能编译配置。


#3

为啥byte compile宏就不用先加载了?


我信了doom-emacs的邪,自己也搞了个Make控制的配置。后来我发现不如直接进emacs M-x操作,使用和除虫都方便太多。还有把所有包配置添加到一个钩子最后运行里解决依赖问题,也是无谓的复杂。果然这种添加复杂度的骚操作还是少搞为妙www


#4

没怎么看懂,general肯定是放最前面直接加载啊,总不能把它lazy了,因为打开编辑器总要按按键的嘛。


#5

和以前只在编译的時後 (require 'cl) 道理一样


#6

use package 有个after keyword。 解决依赖问题的1。可以参考下?

我全部 use package 现在.


#7

所以我说是个不是问题的问题 - 这种依赖问题很少见,而且手动排一下顺序就可以解决。但是手动排顺序没有这样用系统确保来的舒服…


#8

哦哦你是说全部byte compile,我理解错了


#9

楼主似乎把简单问题复杂化了。既然general是楼主基本的库,直接在最前面load就好了。就好比你想用use-package,但还要设计另外一套来控制加载它一样,岂不是多此一举?


#10

有道理,general在我的认知里没有usepackaeg那么基本,不过你这么一说,如果大部分配置都用到那确实是基本库,可以提前加载一下。