为什么必须将每个程序包添加到加载路径?(或我的init文件中的require'package问题)


17

每次我从“程序包菜单”安装程序包时,如果尝试require在init文件中尝试安装它,除非手动将其添加到加载路径,否则都会收到错误消息:

(add-to-list 'load-path "/home/nick/.emacs.d/elpa/use-package-20141220.1645")

(require 'use-package-autoloads)
(require 'use-package)

太乏味了。通常,软件包路径包含版本号。如果软件包已更新,则必须手动编辑加载路径。

有什么办法可以自动化吗?

Answers:


23

TL; DR:

将以下行添加到init文件(.emacs.d/init.el.emacs)的顶部:

(package-initialize)

说明

创建更多Emacs可能会使用的文件user-init-file绝对不是正确的方法。因为手册没有说出发生冲突时最好的方式,至少在您引用的部分中没有,所以这样做只会增加混乱-现在我们不知道哪个实际上是user-init-file(您可能想要的值)进行检查以找出答案)。

因此,首先删除所有候选者,除非~/.emacs.d/init.el通常是(用户)首选,因为它不会造成不正当的混乱,$HOME并且允许使用版本库将所有Emacs配置文件(包括最重要的一个)保留在版本控制下,仅用于存储库。 Emacs。

默认情况下,在加载用户的init文件package-initialize ,Emacs会调用。这样做是完全可以的,因为当今大多数用户使用package.el- 安装软件包,因此他们不必为使这些软件包可用而做任何事情。

另一方面,不是每个人都这样做,因此应该可以打电话package-initialize。通过添加(setq package-enable-at-startup nil)到用户的init文件中可以防止该函数被调用(您还可以把它放到哪里?)。

package-initialize无法在用户进行更改以告知Emacs不执行之前被调用,因此必须加载init文件之后执行。只要用户只安装软件包,然后按原样使用它们,或者使用工作正常的“自定义”界面自定义它们即可。但是,如果要使用elisp自定义软件包,则必须load-path在使用它们定义的功能之前确保它们确实在使用中。

这很容易做到并且有据可查(如果我先查了一下,就不必编写上面的大部分内容了:-/

加载init文件后自动进行软件包加载的原因是,用户选项仅在加载init文件后才收到其自定义值,包括影响打包系统的用户选项。在某些情况下,您可能希望在init文件中显式加载程序包(通常是因为init文件中的其他代码取决于程序包)。在这种情况下,您的初始化文件应调用函数package-initialize。您有责任确保package-load-listpackage-initialize通话之前设置相关的用户选项,例如(请参见下文)。您还应该设置 package-enable-at-startupnil,以避免在处理init文件后再次加载软件包。另外,您可以选择在启动时完全禁止软件包加载,然后调用命令“ Mx package-initialize”手动加载软件包。

所以:

;;; .emacs.d/init.el -- the `user-init-file'

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

(require 'use-package)

(use-package some-package
  :init (setq some-package-variable "foobar")

    ...

;;; .emacs.d/init.el ends here

当然,该问题(或其他问题)也可能Symbol's function definition is void: use-packge是输入文件中存在输入错误,并且直到您将其键入emacs.se才发生。



它是确定使用(require 'use-package)(package-initialize)
陈力

3

我认为应该提到此堆栈溢出答案中提到的after-init-hook解决方案:

(defun my-packages-init ()
  (require 'some-great-package))

(add-hook 'after-init-hook 'my-packages-init)

我以为这是应该执行的方式,但是其他答案提供了有关其他执行方式的信息。


0

下面将所有目录添加~/.emacs.d/site-lisp到加载路径,因此您只需require打包即可完成:

(let* ((my-lisp-dir "~/.emacs.d/site-lisp/")
       (default-directory my-lisp-dir)
       (orig-load-path load-path))
  (setq load-path (cons my-lisp-dir nil))
  (normal-top-level-add-subdirs-to-load-path)
  (nconc load-path orig-load-path))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.