第 12 章:包管理
第 12 章:包管理
12.1 包管理概览
Emacs 有多种包管理方案,理解它们的关系是构建稳定配置的基础。
包管理器对比
| 管理器 | 来源 | 特点 | 适合场景 |
|---|
| package.el | 内置 | 从 ELPA/MELPA 安装 | 简单配置 |
| straight.el | 第三方 | 从 Git 源安装,可复现 | 精确控制版本 |
| quelpa | 第三方 | 从任意 Git 仓库安装 | 未发布包 |
| Borg | 第三方 | Git submodule 方式 | 极简主义者 |
源配置
;; package.el 源配置
(require 'package)
(setq package-archives
'(("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")
("nongnu" . "https://elpa.nongnu.org/nongnu/")))
;; 清华镜像(国内加速)
(setq package-archives
'(("melpa" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
("gnu" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
("nongnu" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/nongnu/")))
(package-initialize)
源的说明
| 源 | 全称 | 内容 |
|---|
| GNU ELPA | GNU Emacs Lisp Package Archive | 官方维护的包 |
| NonGNU ELPA | NonGNU ELPA | 非 GNU 但官方认可的包 |
| MELPA | Milkypostman’s Emacs Lisp Package Archive | 社区维护的最新包 |
| MELPA Stable | — | MELPA 的稳定版本(tag) |
12.2 package.el(内置)
基本操作
| 快捷键/命令 | 说明 |
|---|
M-x list-packages | 列出所有可用包 |
M-x package-install | 安装包 |
M-x package-delete | 删除包 |
M-x package-refresh-contents | 刷新包列表 |
M-x package-autoremove | 自动删除无用依赖 |
list-packages 操作
在 *Packages* 缓冲区中:
i → 标记安装
d → 标记删除
u → 取消标记
U → 标记所有可升级的包
x → 执行标记的操作
RET → 查看包详情
f → 按名称过滤
/ k → 按关键字过滤
/ n → 按名称过滤
package.el 的局限
⚠️ package.el 的常见问题:
1. 不可复现 — 包版本不固定,不同时间安装可能不同
2. 依赖冲突 — 无法处理同一包的不同版本
3. 无法从 Git 仓库直接安装
4. 无法 pin 到特定 commit
5. 启动时加载较慢
12.3 straight.el(推荐)
straight.el 是一个可复现的包管理器,从 Git 源直接安装包。
安装
;; 直接安装(推荐方式)
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el"
user-emacs-directory))
(bootstrap-version 6))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
基本用法
;; 安装包
(straight-use-package 'magit)
;; 安装并配置
(straight-use-package
'(magit :type git :host github :repo "magit/magit"))
;; 从非标准源安装
(straight-use-package
'(my-package :type git :host github :repo "user/my-package"
:branch "develop"))
;; 锁定版本(可复现)
;; 使用 straight.lock 文件
(straight-freeze-versions) ; 冻结当前版本
(thaw-versions) ; 恢复冻结版本
;; 更新所有包
(straight-pull-all)
;; 重建包
(straight-rebuild-all)
straight.el 优势
| 特性 | 说明 |
|---|
| 可复现 | straight.lock 锁定所有包的 commit |
| Git 原生 | 直接从 Git 安装,支持任何分支/commit |
| 懒加载 | 可以不立即加载包 |
| 版本管理 | straight-freeze-versions / straight-thaw-versions |
| 集成 use-package | 与 use-package 无缝配合 |
12.4 use-package(声明式配置)
use-package 是 Emacs 29+ 内置的声明式包配置宏,让你的配置清晰、高效。
基本语法
;; 最简单的用法
(use-package magit)
;; 等价于:
(require 'magit)
;; 完整语法
(use-package package-name
:ensure t ; 自动安装(package.el)或 straight.el
:defer t ; 延迟加载
:after other-package ; 在某个包加载后加载
:hook (mode . func) ; 挂钩到某个模式
:bind ("C-c m" . cmd) ; 绑定快捷键
:config ; 加载后执行
:init ; 加载前执行
:custom ; 设置自定义变量
:diminish ; 在模型栏隐藏
:commands (cmd1 cmd2) ; 声明命令以触发加载
:mode ("\\.ext\\'" . mode) ; 文件关联
:interpreter ("name" . mode) ; 解释器关联
)
常用配置示例
;; 1. 基本配置
(use-package which-key
:ensure t
:config
(which-key-mode 1))
;; 2. 延迟加载
(use-package magit
:ensure t
:defer t
:bind ("C-x g" . magit-status))
;; 3. Hook 加载
(use-package flycheck
:ensure t
:hook (prog-mode . flycheck-mode))
;; 4. 模式关联
(use-package web-mode
:ensure t
:mode ("\\.html\\'" "\\.vue\\'")
:config
(setq web-mode-markup-indent-offset 2))
;; 5. After 加载
(use-package evil-collection
:ensure t
:after evil
:config
(evil-collection-init))
;; 6. 自定义变量
(use-package org
:custom
(org-directory "~/org")
(org-agenda-files '("~/org/agenda"))
(org-startup-indented t))
;; 7. 绑定多个按键
(use-package avy
:ensure t
:bind (("C-:" . avy-goto-char)
("C-'" . avy-goto-char-2)
("M-g w" . avy-goto-word-1)))
;; 8. 隐藏模型栏标识
(use-package diminish
:ensure t)
(use-package abbrev
:diminish abbrev-mode)
;; 9. 条件加载
(use-package lsp-mode
:ensure t
:if (executable-find "pyright")
:hook (python-mode . lsp))
;; 10. 嵌套配置
(use-package org
:config
(use-package org-roam
:ensure t
:after org
:config
(org-roam-db-autosync-mode)))
use-package 关键字顺序
;; 推荐的关键字顺序
(use-package PACKAGE-NAME
;; 1. 加载控制
:ensure ; 是否安装
:if / :when / :unless ; 条件加载
:after ; 依赖
:defer ; 延迟
:demand ; 立即加载
;; 2. 触发加载
:commands ; 命令触发
:bind ; 按键触发
:mode ; 文件模式触发
:interpreter ; 解释器触发
:hook ; Hook 触发
;; 3. 自定义变量
:custom ; 设置变量
:custom-face ; 设置 face
;; 4. 配置
:init ; 加载前执行
:config ; 加载后执行
;; 5. 显示
:diminish ; 隐藏模型栏
:delight ; 替换模型栏显示
)
12.5 straight.el + use-package 集成
;; 这是目前最推荐的组合方式
;; 1. 安装 straight.el(见 12.3 节)
;; 2. 让 use-package 使用 straight.el
(straight-use-package 'use-package)
(setq straight-use-package-by-default t)
;; 3. 现在所有 use-package 调用都会通过 straight.el 安装
(use-package magit) ; 自动从 MELPA Git 仓库安装
(use-package org-roam) ; 自动安装
;; 4. 如果需要从特定源安装
(use-package my-package
:straight (:host github :repo "user/my-package"
:branch "main"
:files ("*.el" "*.org")))
12.6 自动更新策略
;; 策略 1:手动更新(推荐)
;; 每周运行一次
;; M-x straight-pull-all (straight.el)
;; M-x package-update-all (package.el)
;; 策略 2:自动检查更新
(use-package auto-package-update
:config
(setq auto-package-update-delete-old-versions t
auto-package-update-hide-results t)
(auto-package-update-maybe))
;; 策略 3:Doom Emacs 方式
;; doom upgrade → 更新 Doom 和所有包
12.7 常见问题排查
| 问题 | 解决方案 |
|---|
| 包安装失败 | M-x package-refresh-contents 刷新后重试 |
| 版本冲突 | straight-freeze-versions 锁定版本 |
| 加载错误 | emacs --debug-init 查看错误堆栈 |
| 字节码过期 | straight-rebuild-all 重新编译 |
| Hook 不生效 | 确认 use-package 的 :hook 语法正确 |
| 包找不到 | 检查 package-archives 配置 |
12.8 本章小结
| 管理器 | 核心功能 | 适用场景 |
|---|
| package.el | package-install, list-packages | 简单配置 |
| straight.el | straight-use-package, freeze/thaw | 精确版本控制 |
| use-package | :ensure, :config, :hook, :bind | 声明式配置 |
| 推荐组合 | straight.el + use-package | 最佳实践 |
12.9 扩展阅读
← 上一章 第 11 章:Elisp 编程 | 下一章 → 第 13 章:补全系统