在我看来,内置在Emacs 24上的新Package系统在正确加载和初始化已安装的软件包时存在一些缺陷。
最近,我升级到Emacs 24.1.1,该版本于2012年6月10日发布,我一直在尝试使用内置的软件包系统,并使用它安装了几个软件包,但它们都有类似的问题相关自动加载和初始化。
例如,我使用名为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变量使其按预期工作,但是,这似乎首先打破了包装系统的整个目的......
有什么想法?有没有更好的方法,或者我们现在是否忍受这种限制?
答案 0 :(得分:78)
值得注意的是为什么 Emacs推迟了软件包初始化:
参见 C-h i g (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
手动加载您的包。
因此,在调用package
之前,请确保您的init文件处理package-initialize
自定义组 1 中的变量所需的任何非默认值 - 并且每当自定义包库配置时都保持这种方法 - 应该可以这样做。
或者,因为after-init-hook
在标准包初始化完成后运行,所以您可以使用它来评估依赖于包的任何init代码。因此,您可以改为编写:
package-initialize
(add-hook 'after-init-hook 'my-after-init-hook)
(defun my-after-init-hook ()
;; do things after package initialization
)
将需要初始化包系统的代码放在该函数中。
因人而异。
(nb我没有测试过post-init方法,因为我没有真正使用package.el;但是我确实确认了启动代码中的事件序列,所以我相信它会像所描述的那样工作。)
1 M-x customize-group
RET package
RET
答案 1 :(得分:42)
默认情况下,您在package.el
加载.emacs
后会激活您使用.emacs
安装的软件包。
为了能够在(setq package-enable-at-startup nil)
(package-initialize)
结束之前使用它们,您需要使用以下命令激活它们:
{{1}}