46

在我看来,Emacs 24 内置的新包系统在正确加载和初始化已安装的包时存在一些缺陷。

最近,我升级到 2012 年 6 月 10 日发布的 Emacs 24.1.1,我一直在尝试使用内置的包系统并使用它安装了几个包,但它们都有与自动加载和初始化。

例如,我使用了一个名为的包smex,它提供了使用M-x和弦的增强功能。它需要您为 定义一个键M-x,所以我(global-set-key (kbd "M-x") 'smex)在我的init.el文件中添加了。但是在启动 emacs 之后,我按下M-x和弦并收到消息“符号的函数定义无效:smex” ......如果我也放入(require 'smex)我的 init.el 文件,我收到错误消息“文件错误:无法打开加载文件,smex "

将 smex 的位置添加到 load-path 变量使其按预期工作,但是,这似乎违背了首先拥有一个包系统的整个目的......

有什么想法吗?有没有更好的方法,或者我们现在是否接受这个限制?

4

2 回答 2

79

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

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

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

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

或者,因为after-init-hook在标准包初始化完成后运行,您可以使用它来评估任何依赖于包的初始化代码。因此package-initialize,与其直接在 init.el 中调用,不如编写:

(add-hook 'after-init-hook 'my-after-init-hook)
(defun my-after-init-hook ()
  ;; do things after package initialization
  )

将需要初始化的包系统的代码放在该函数中。

YMMV。

(nb 我没有测试过初始化后的方法,因为我并没有真正使用 package.el;但我确实确认了启动代码中的事件顺序,所以我相信它会按照描述的那样工作。)

1 M-x customize-group RET package RET

于 2013-09-13T09:44:39.763 回答
44

默认情况下,您安装的软件包在加载package.el会被激活。为了能够在结束之前使用它们,您需要使用以下命令激活它们:.emacs.emacs

(setq package-enable-at-startup nil)
(package-initialize)
于 2012-06-21T14:41:38.583 回答