「GNU Emacs」- 包管理系统(ELPA, Emacs Lisp Package Archive)

ELPA & package.el

ELPA(Emacs Lisp Package Archive)是 Emacs 的扩展仓库,从 GNU Emacs 24 开始引入。还有很多其他非官方仓库,比如 GnuELPA、Marmalade,以及我们用的最多的 MELPA 仓库。

package.el 是 Emacs 的扩展管理器(实际上是“库”(lib)),包含很多用于管理扩展的函数及命令,可以从 ELPA 中下载扩展、安装扩展,同时也支持搜索、管理等等功能,目的是简化 Emacs 扩展的安装。

配置及使用

第一步、配置扩展仓库

修改 .emacs 或者 ~/.emacs.d/init.el 文件,添加如下配置:

(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/") ;; GNU ELPA repository (Offical)
                         ("melpa" . "https://melpa.org/packages/") ;; MELPA repository
                         ("melpa-stable" . "https://stable.melpa.org/packages/") ;; MELPA Stable repository
                         ("org" . "http://orgmode.org/elpa/"))) ;; Org-mode's repository

或者,使用 M-x customize-variable [RET] package-archives [RET] 进行配置:
1)Archive name: 填写仓库名,比如 gnu、melpa、melpa-stable 等等;
2)URL or directory name: 填写仓库地址,比如 https://melpa.org/packages/ 地址;

在完成仓库配置后,执行 M-x package-refresh-contents 指令,来创建扩展索引缓存(实际上是下载 archive-contents 文件,并进行处理,然后保存到 /.emacs.d/elpa/archives/<archive-name>/ 目录,该文件保存在某个仓库内全部的全部扩展、下载地址等等信息)。

第二步、安装插件(键盘操作)

1)Type M-x list-packages to open the package list.
2)Press ‘i’ to mark for installation, ‘u’ to unmark,
3)and ‘x’ to perform the installation.
4)Press ‘RET’ to read more about installing and using each package.

使用 ELPA 安装的插件,位于 $HOME/.emacs.d/elpa/ 目录。

其他常见操作

更新插件(键盘操作)

如下方法,将升级全部可升级的扩展:
0)更新缓存:M-x package-refresh-contents
1)查看扩展:M-x list-packages
2)标记升级:Then, press [U] to mark all upgradable packages to be upgraded.
3)执行升级:Last, press [x] to perform the new updates.

如果进需要更新_特定_扩展,重新安装(reinstall)即可:
1)更新缓存:M-x package-refresh-contents
2)更新扩展:M-x package-reinstall <package>

删除插件(键盘操作)

1)查看扩展:M-x package-list-packages
2)搜索扩展:C-s django-snippets
3)标记删除:Mark the package for deletion by typing ‘d’
4)执行删除:Execute by typing ‘x’

或者,使用 M-x package-delete RET "<package name>" 命令,直接删除扩展;

插件降级

如果,在升级后,出现插件功能异常或者其他问题,我们需要降级。这也是可以的,参考 ELPA policy 部分。

重新编译全部插件

M-: (byte-recompile-directory package-user-dir nil ‘force) [RET]

扩展加载流程(原理简述)

Emacs start up => Load init file & abbrev file => (package-initialize) => `after-init-hook`

使用 (setq package-enable-at-startup nil) 指令,可以关闭扩展的自动加载。

因此,我们不应该在初始化文件(init.el)中进行扩展的初始化,因为,在执行初始化文件时,扩展还没有加载。

但是,以下几种操作是可行的:
1)可以修改用于扩展的自定义变量;
2)不依赖于扩展加载的 auto-mode-alist 修改:(add-to-list 'auto-mode-alist '("\\.gradle" . groovy-mode))
3)当扩展加载成功后执行的 Hook:(add-hook 'groovy-mode-hook (lambda () (setq tab-width 4)))
4)快捷键绑定;
5)某些扩展的初始化,在加载扩展前,可以使用 eval-after-load 完成设置;
6)可以指定 (package-initialize) 来尽早加载扩展,然后便可使用 (require) 引入扩展并进行设置;
7)如果上面的方法都存在问题,可以使用 (add-hook ‘after-init-hook ‘cycbuf-init) 进行处理;

常见问题汇总

配置重新加载

在修改配置文件(~/.emacs、~/.emacs.d/init.el)后,使用以下方式重新加载配置:
1)重新加载文件:M-x load-file [RET] ~/.emacs [RET]
2)执行当前缓冲:M-x eval-buffer [RET]
3)重启 Emacs 实例

相关链接

EmacsWiki / ELPA
Milkypostman’s Emacs Lisp Package Archive

参考文献

GNU Emacs Lisp Package Archive
Getting Started – MELPA Stable
EmacsWiki: InstallingPackages
emacs – How to remove installed elpa package – Stack Overflow
How to upgrade packages installed by ELPA in Emacs? – SysTutorials
How to easily update one elpa package? : emacs
use-package Tries To Load Outdated MELPA Package?
Emacs , use-package and package-refresh-contents
How to rebuild ELPA packages after upgrade of Emacs – Stack Overflow
loading – Reload configurations without restarting Emacs – Stack Overflow