Emacs 24包系统初始化问题

45

在Emacs 24内置的新打包系统中,当正确加载和初始化安装的软件包时,似乎存在一些缺陷。

最近,我升级到了发布于2012年6月10日的Emacs 24.1.1版本,并尝试使用内置的软件包系统,并使用它安装了几个软件包,但它们都有与autoload和初始化相关的类似问题。

例如,我使用一个名为smex的软件包,它提供了增强M-x命令的功能。 它要求您为M-x定义一个键,因此我在我的init.el文件中添加了(global-set-key (kbd "M-x") 'smex)。 但是,在启动emacs后,我按下M-x组合键,然后收到消息"Symbol's function definition is void: smex"...如果我还在我的init.el文件中添加(require 'smex),则会收到错误消息"File error: Cannot open load file, smex"

将smex的位置加入load-path变量使其正常工作,但这似乎违背了首先拥有软件包系统的初衷...

有什么想法吗? 还有更好的方法,或者我们暂时接受这种限制吗?

2个回答

79

值得注意的是为什么Emacs推迟了包初始化:

请参阅C-hig (emacs) Package Installation RET,特别是这段话:

自动加载包发生在加载init文件之后的原因是用户选项只有在加载init文件后才会接收到其自定义值,其中包括影响打包系统的用户选项。在某些情况下,您可能希望在init文件中显式加载软件包(通常是因为您的init文件中的其他代码依赖于软件包)。在这种情况下,您的init文件应调用函数package-initialize。由您来确保设置了相关的用户选项,例如package-load-list(请参见下文)在调用package-initialize之前已经准备好。还应将package-enable-at-startup设置为nil,以避免在处理init文件后再次加载包。或者,您可以选择完全禁止启动时加载软件包,并调用命令M-x package-initialize手动加载软件包。

因此,只要您确保init文件在调用package-initialize之前处理了package自定义组中变量的任何非默认值,并且在自定义软件包库配置时保持这种方法,就可以这样做。

或者,因为after-init-hook在标准软件包初始化完成后运行,您可以使用它来评估任何依赖于软件包的init代码。因此,而不是在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; 但我确认了启动代码的顺序,所以我相信它会按照描述的那样工作。)

1 M-x customize-group RET package RET


5
我不知道为什么这个答案得到的票数很少,也没有被采纳……根据你所解释的情况,被采纳的答案提供的解决方案甚至开始看起来像一个hack(译注:指权宜之计、临时应付的方法)。 - Erik Kaplun
非常好的答案!在使用package-initialize加载包之后,我还需要require我的包吗? - Veritas
1
Veritas:这取决于软件包。编写良好的软件包通常会包含自动加载 cookie(由软件包管理器处理)以供重要命令使用,这样你就不太需要 require 它们(反过来又可以提高启动时间)。没有自动加载的软件包仍然需要被 require(或以任何方式加载)。 - phils

43

package.el 安装的包在加载你的 .emacs 文件之后默认被激活。 如果想要在 .emacs 加载完成之前使用它们,需要使用以下命令进行激活:

(package-initialize)
(setq package-enable-at-startup nil)
(package-initialize)

1
我认为phils的答案比这个更有价值,甚至是正确的;他还解释了原因。 - Erik Kaplun
5
@ErikAllik,点踩是为了报告信息不准确。你应该只赞同其他更准确的答案。要了解为什么接受了这个答案,只需看日期即可。它比另一个答案早写了15个月。 - Nicolas Dudebout
1
这只是为了稍微平衡一下分数——可能是不恰当的行为 :) - Erik Kaplun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接