在我看来,Emacs 24 上内置的新 Package 系统在正确加载和初始化已安装的软件包时存在一些缺陷。
最近,我升级到 Emacs 24.1.1,它在 2012 年 6 月 10 日实现,我一直在尝试使用内置的软件包系统并安装了几个使用它的软件包,但它们都有与自动加载和初始化相关的类似问题。
例如,我使用一个名为 smex
的包,它提供了使用 M-x
和弦的增强功能。它需要你定义一个键 M-x
,所以我在我的init.el
文件中添加了(global-set-key (kbd "M-x") 'smex)
。但是在启动 emacs 后,我按下M-x
和弦,我收到消息"符号的函数定义无效:smex"......如果我也在我的 init.el 文件中(require 'smex)
,我会收到错误消息"文件错误:无法打开加载文件,smex"
将 smex 的位置添加到负载路径变量中使其按预期工作,但是,这似乎首先破坏了拥有包系统的全部目的......
有什么想法吗?有没有更好的方法,或者我们现在忍受这个限制?
值得注意的是为什么 Emacs 推迟了软件包初始化:
参见 C-hig (emacs) Package Installation
RET,特别是:
加载 init 后自动加载包的原因 文件是用户选项仅在之后接收其自定义值 加载 init 文件,包括影响 包装系统。 在某些情况下,您可能需要加载包 在您的 init 文件中显式(通常是因为 初始化文件依赖于包)。 在这种情况下,您的初始化文件应该 调用函数
package-initialize
。 由您来确保 设置了相关的用户选项,例如package-load-list
(见下文) 在package-initialize
呼叫之前。 您还应该设置package-enable-at-startup
nil
,以避免加载包 再次处理初始化文件后。 或者,您可以选择 在启动时完全禁止包加载,并调用命令M-x package-initialize
手动加载包。
因此,只要您确保 init 文件在调用 package-initialize
之前处理package
自定义组1 中变量所需的任何非默认值 - 并且您在自定义包库配置时都保持此方法 - 这样做应该是可以的。
或者,由于after-init-hook
在标准包初始化完成后运行,因此您可以使用它来评估依赖于包的任何初始化代码。因此,与其直接在 init.el 中调用package-initialize
,不如编写:
(add-hook 'after-init-hook 'my-after-init-hook)
(defun my-after-init-hook ()
;; do things after package initialization
)
将需要初始化包系统的代码放在该函数中。
扬子晚报.
(注我还没有测试过初始化后的方法,因为我并没有真正使用 package.el;但我确实确认了启动代码中的事件顺序,所以我相信它会按照描述工作。
1M-x customize-group
RET package
RET
,使用 package.el
安装的软件包在加载.emacs
后激活。为了能够在.emacs
结束前使用它们,您需要使用以下命令激活它们:
(setq package-enable-at-startup nil)
(package-initialize)