我把macroexp.el(c)没收,那么emacs 到底是在哪里load到macroexpand-all的?

起因是来windows下看看有没有大佬编译的更好的版本, 还真找到一个 https://github.com/juanjosegarciaripoll/emacs-build, 下来装doom 试试, 结果一安装

.\doom.cmd install
Eager macro-expansion failure: (void-variable  )
Eager macro-expansion failure: (void-variable  )
Error in Doom Emacs core: "cli/lib/lib.el", (void-variable  )

这是宏展开的问题呀, 开启了--debug-init 也没有更多显示, 头秃. 好在搜到一位大神的解答: https://emacs.stackexchange.com/questions/54455/how-to-get-a-stack-trace-for-eager-macro-expansion-failure.
逻辑是, 改造macroexp.el 中的internal-macroexpand-for-load, 使得返回错误消息时带回更多参数.
我觉得好有道理, 马上开始改造:

(defun internal-macroexpand-for-load (form full-p)
...
;;     (message "Eager macro-expansion failure: %S" err)
       (message "Eager macro-expansion failure: %S form: %S load file: %S" err form load-file-name)
       form)))))

然后我把这个函数依次放入init.el, early-init.el, 都没有什么变化, 还是缺乏信息.
于是, 我决定直接修改share\emacs\27.1\lisp\emacs-lisp\macroexp.el, 并把macroexp.elc macroexp.el.gz, 都移走. 再来, 还是没有更多信息!!

我恶向胆边生, 都删光, 看你没有这个macroexp.el*怎么玩!!
燃鹅 emacs -Q 启动后, macroexpand-all这个函数照常可以运行 :scream:,

C-h f查找帮助文档, 得到的是:

macroexpand-all is a compiled Lisp function.

(macroexpand-all FORM &optional ENVIRONMENT)

  Probably introduced at or before Emacs version 22.1.

Return result of expanding macros at all levels in FORM.
If no macros are expanded, FORM is returned unchanged.
The second optional arg ENVIRONMENT specifies an environment of macro
definitions to shadow the loaded ones for use in file byte-compilation.

不再显示源文件了, 可还照常能用, internal-macroexpand-for-load也是如此,这是什么原理??
我再三确认了, emacs目录没macroexp.* 文件, 而系统PATH上也没有别的emacs版本了.
我把macroexp.*都删掉,那它是在哪里加载到函数macroexpand-all的呢? 我在init.el重定义又为什么不起作用呢?
头秃, 求大神指导!! :scream:

大概率是因为 pdumper, Emacs 为了加快启动速度, build 的过程里面会把将来启动时候需要加载的 Elisp 对象 dump 成一个二进制文件, 像 macroexp 一般都是从这个文件加载, 而不是 elc 之类.

想实验的话可以找找 emacs.pdmp 这个文件, 把它也删掉, 再启动 Emacs 的时候很可能就会报 macroexp 相关的错了.

1 个赞

至于为啥 init.elearly-init.el 没作用, 可以看下 doom.cmd 的内容, 实际上是执行了

emacs --quick --script .\doom -- %*

也就是去运行同目录下面的 doom 这个脚本, init.el 那些都是没加载的. 想改函数定义的话可以在这个文件里改改试试.

1 个赞

谢谢, 您分析得完全正确, 给大佬跪了! !
pdumper文件在libexec/emacs/27.1.90/x86_64-w64-mingw32/emacs.pdmp!
至于doom我还得慢慢学习, 如果还有不懂还得向您请教 :joy: