我当然是运行了 occur-mode 后,去 message buffer 查看是否输出了 hello。
从你的描述来看,确实是 post-init-xxx
之前,occur 已经加载了。按常理推测(我不用 spacemacs),post-init-xxx
就是 with-eval-after-load / hook
的马甲。with-eval-after-load
里 with-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 替代,取得类似的效果。
这个分析很到位。內建的包,那我直接不用 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)
指出个骚操作,于问题本身关系不大。