with-eval-after-load 无效

我当然是运行了 occur-mode 后,去 message buffer 查看是否输出了 hello。

从你的描述来看,确实是 post-init-xxx 之前,occur 已经加载了。按常理推测(我不用 spacemacs),post-init-xxx 就是 with-eval-after-load / hook 的马甲。with-eval-after-loadwith-eval-after-load 显然是不被调用的。

建议,理清楚 post-init / pre-init / init 的顺序,以及原生 with-eval-after-loade / hook 的区别。

另外,with-eval-after-load 里边无需 (progn ...)

我查了一下 occur-mode 所在的包叫 replace.el, 你用 (with-eval-after-load 'replace) 呢?

而且occur-mode确定被load了?看看能不能describe这个符号(occur-mode)

我理清了…你去看看?你可以测试一下。 post-init 跟 with-eval-after-load 没有关系,请看上面的跟帖。

并不是只有直接运行 occur-mode 才会加载那个包

注意 occur-mode 隶属于 replace.el, 后者是 emacs 25 内建的包,并且我搜索了一下 replace.el 中并没有 provide 语句,也就是说没有名为 replace 的 feature,所以这也是为什么你不能对它使用 with-eval-after-load 的原因

你要 with-eval-after-load 的话,至少先确保这个 feature 存在,或者使用文件名代替。鉴于 occur-mode 是一个 mode 类的命令,你可以用 occur-mode-hook 替代,取得类似的效果。

2 个赞

这个分析很到位。內建的包,那我直接不用 eval-after-load 就可以了,直接定义:

(defun my-edit/post-init-occur-mode ()
      (define-key occur-mode-map (kbd "C-c C-e") 'occur-edit-mode))

测试了下,确实可以,感谢这么晚还在帮助解答问题哈。

补充:其实关键还是没有 occur-mode 这个 feature 的问题吧。

是的,对 (featurep 'occur-mode) 求值得到的结果是 nil 而且 occur-mode 所在的 replace.el 也不是一个 feature:

(featurep 'replace) => nil

但是 spacemacs 确实是把 occur-mode 当作一个 package 的:

(configuration-layer/package-used-p 'occur-mode) => t

provide 只是用来指明这个包提供了哪个特性,不一定要和文件名和 require 对应,with-eval-after-load 的文档也说明第一个参数不一定要是 feature


举例:我一般用 feature 来指示配置中的某个文件是否被编译,远比用全局变量优雅。因为 setq 之前还要 defvar,不然 debug level 提高以后会报错。

上面帖子里没有说文件名一定要和 require 对应吧?

看了一下 with-eval-after-load ,第一个参数是 feature 或文件,所以使用 (with-eval-after-load 'occur-mode) 是肯定不对的,因为 occur-mode 不是一个 feature,也不是一个文件。

;;;###autoload
(defmacro self-byte-compile (&optional arg)
  "Auto byte compile current loading file. If AEG, load the compiled file."
  (cond ((featurep 'wizard 'install)
         '(eval-when 'eval
            (byte-compile-file load-file-name arg)))
        ((featurep 'inferno 'autocomp)
         '(eval-when 'eval
            (byte-recompile-file load-file-name nil 0 arg)))))

;; Enable auto byte compile.
(self-byte-compile t)

指出个骚操作,于问题本身关系不大。