You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Doom Emacs延迟加载场景下,如何程序化使用未加载包的变量?

Doom Emacs延迟加载包的按键绑定问题解决

问题场景

尝试在Doom Emacs的延迟加载机制下,为未加载的包绑定自定义按键映射,原代码如下:

(pcase-dolist (`(,package ,keymap) '((eww eww-mode-map)
                                     (info Info-mode-map)
                                     (man Man-mode-map)
                                     (nov nov-mode-map)
                                     (devdocs devdeocs-mode-map)))
  (eval-after-load package
    (evil-define-key* 'normal keymap "j" #'my/pixel-scroll-down)))

存在的问题:eval-after-load内部的变量会被立即求值,而非等到包加载时才使用对应变量,导致按键绑定无法正确生效。

解决方案

修正后的代码

(pcase-dolist (`(,package ,keymap) '((eww eww-mode-map)
                                     (info Info-mode-map)
                                     (man Man-mode-map)
                                     (nov nov-mode-map)
                                     (devdocs devdocs-mode-map)))
  (let ((pkg package)
        (km keymap))
    (eval-after-load pkg
      (lambda ()
        (evil-define-key* 'normal km "j" #'my/pixel-scroll-down)))))

关键说明

  1. 局部变量绑定:用let将循环中的package和keymap绑定到局部变量pkg和km,避免循环变量被后续迭代覆盖,确保每个eval-after-load回调能获取到对应包的正确参数。
  2. 延迟执行逻辑:将evil-define-key*的调用包裹在lambda函数中,eval-after-load会在包加载完成后执行这个lambda,此时才会对km(对应包的按键映射变量)求值,保证绑定操作在包完全加载后执行。
  3. 拼写修正:原代码中devdeocs-mode-map为拼写错误,修正为devdocs-mode-map。

原代码失效原因

  • evil-define-key*是宏,会在pcase-dolist循环时立即展开,此时keymap变量对应的包按键映射可能尚未初始化,导致绑定无效。
  • 未使用局部变量保存循环参数时,所有eval-after-load的回调会共享同一个循环变量,最终只会使用最后一次迭代的参数值。

内容的提问来源于stack exchange,提问作者Maor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:48:17