强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Emacs 完全指南 / 第 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 ELPAGNU Emacs Lisp Package Archive官方维护的包
NonGNU ELPANonGNU ELPA非 GNU 但官方认可的包
MELPAMilkypostman’s Emacs Lisp Package Archive社区维护的最新包
MELPA StableMELPA 的稳定版本(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.elpackage-install, list-packages简单配置
straight.elstraight-use-package, freeze/thaw精确版本控制
use-package:ensure, :config, :hook, :bind声明式配置
推荐组合straight.el + use-package最佳实践

12.9 扩展阅读


← 上一章 第 11 章:Elisp 编程 | 下一章 → 第 13 章:补全系统