with-eval-after-load 无效

我在自己的 layer 里面的 post-init-occur-mode 函数里写了 with-eval-after-load,但是 occur 运行后发现无效,代码如下:

(defun my-edit/post-init-occur-mode ()
  (with-eval-after-load 'occur-mode
    (progn
      (message "hello")
      (define-key occur-mode-map (kbd "C-c C-e") 'occur-edit-mode))))

message 没有被执行,是语句哪儿错了?

看看log里 (defun my-edit/post-init-occur-mode () 被加载了吗

被加载了,把 message 放在 with-eval-after-load 外面,运行 occur-mode 后,是可以加载的

with-eval-after-load 不要放在 post-init 函数里,没有作用的。因为 post-init 是在 occur-mode 加载后才执行,就没有必要再加一层 with-eval-after-load 了。

with-eval-after-load 一般是放在 init 函数体内,用来强调需要在另一个包之后加载,比如:

(defun my-layer/init-A-package ()
  (use-package A-package
     ...
    :init
    (with-eval-after-load 'B-package
      (do-something))))

是在初始化 A 的过程中,需要函数 (do-something) 在 B 加载后执行。

你理解错了吧,post-init 不是表示在 package load后执行,而是加载layer时候执行,如果一个package使用 autoload 的方式加载,就算这个 package还没有被实际 load,但是仍然会执行 post-init。

init/post-init/pre-init 的执行与package是否加载没有什么联系,这三个函数是一定会执行的(当然,这个package不能被 exclude,被exclude的package 的这三个函数不会执行)

理论上是这样,但是实践上不推荐在 post-init 函数体内 with-eval-after-load

我都是在 pre-initinit 里用 with-eval-after-load,另外也可以在 pre-init 里利用特殊的钩子将代码注入 init

请问这个是从哪里看到的?

对于 spacemacs 来说,在 config.el 里面不是经常会使用 with-eval-after-load 吗?

在 post-init 里面写跟在 config 里面写是一样的啊。如果不能在这里写,只在 init里面写,自定义的 layer哪有那么多 init 方法啊,大部分 package 都已经有 owner 了吧。

补充: 刚搜索了一下 spacemacs 自身的一些layer,也有很多都是这么写的。估计你理解有点错误吧。

这个是我的实践经验总结,哈哈。或者你可以参考一下官方 layer 的写法,我很少见到 post 里面用 with-eval-after-load

当然你可以按照自己的想法搞

你打开 spacemacs 的 .emacs.d 目录,搜索下 post-init,找几个 layer 的 package.el,然后搜索一下 with-eval-after-load,会发现有不少 layer 都是这么写的。

所以问题应该不是这个导致的,我怀疑跟 evilified-state 有关,看明天有哪位大神给解释一下吧。

没有吧,我看大部分都是在 init 函数体内

  1. /Users/Baitianyu/.emacs.d/layers/+lang/clojure/packages.el : (defun clojure/post-init-smartparens ()
  2. /Users/Baitianyu/.emacs.d/layers/+chat/rcirc/packages.el : ((defun rcirc/post-init-persp-mode ()

layer太多了,没有一个一个看,我简单搜了下就看见这两个了,当涉及到 package 依赖的时候,应该不少的吧,不然依赖就没法玩了。

好吧,我可能记错了,抱歉提供了错误的信息。

没事儿哈,大家互相学习

直接eval有效吗

你把 message 放到 with-eval-after-load 外面可以执行,请问是在什么时候执行的呢?感觉不应该在运行 occur-mode 这个命令执行 message 啊

放到 with-eval 外面,按照你的解释应该是启动时就执行 message 了

直接 eval 是指?

恩,不是,是在layer加载的时候执行的,跟 occur-mode 是否 load 没关系,所以我说是 with-eval-after-load 'occur-mode 没有生效。

对的,启动时候就执行了

直接eval with-eval-after-load

放到 with-eval-after-load 的语句是在 occur-mode 包加载时才运行,你的这个因果关系貌似不成立

无效。所以说这句话没有生效的。