面向产品经理的Emacs教程:4. Emacs包管理

· 2245字 · 5分钟

1 Emacs的包管理 🔗

Emacs自带一个包管理器 package.el 用来进行插件的安装、升级等。当然,Emacs发展到今天,也出现了其他各具特色的包管理器如 straight.el, borg 等等,作为新手来说,当然是学习自带的 package.el ,等进一步对Emacs有更多的认识后,可以根据自己的喜好来选择包管理器。

那包管理器有啥作用呢?我们当前的Emacs可以形象地理解为是裸配,缺少很多功能,得益于Emacs的自由,社区大神们给Emacs写了无数的插件,在这些插件的基础上,我们能让Emacs做到意到气到,成为你身体的一部分。而包管理器就是安装这些插件的基础。

2 配置package.el包管理器 🔗

虽然Emacs自带了这个包管理器,但我们还是需要对其进行配置,如添加仓库源、初始化等操作。

下面,我们就在崭新的,刚刚配置好 early-init.elemacs-config.org 文件里配置包管理器。

2.1 配置init.el 🔗

根据模块化配置文件的思想,我们把包管理器相关的核心配置,都统一放到 init.el 这个文件里。

所以,首先,我们需要先进行 init.el 文件tangle相关的配置,其中在 init.el 文件头init.el 文件尾 标题行之间的部分,就是我们需要配置在 init.el 文件里的配置内容,例如我们等会儿要配置的 package.el 包管理器相关的内容就会放在这里。

* init.el
:PROPERTIES:
:HEADER-ARGS: :tangle init.el
:END:
=init.el= 是Emacs的主要配置文件。

* init.el 文件头
#+BEGIN_SRC emacs-lisp
;;; init.el --- The main init entry for Emacs -*- lexical-binding: t -*-
;;; Commentary:

;;; Code:

#+END_SRC

* init.el 文件尾
#+BEGIN_SRC emacs-lisp

(provide 'init)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; init.el ends here
#+END_SRC

至于文件头和文件尾这两个标题行里的内容是啥,这个阶段先不用管,照抄就是了。

2.2 配置package.el 🔗

配置 pacakge.el 的主要步骤是:

  1. 加载 package 这个包
  2. 添加仓库源
  3. 初始化
** package包管理配置
#+begin_src emacs-lisp
(require 'package)
(setq package-archives
	  '(("melpa"  . "https://melpa.org/packages/")
	    ("gnu"    . "https://elpa.gnu.org/packages/")
	    ("nongnu" . "https://elpa.nongnu.org/nongnu/")))

(package-initialize)
#+end_src

2.3 配置use-package 🔗

use-package 是我们安装的第一个插件,这个插件能让Emacs配置更加结构化,更加清晰,它的的本质是宏。

关于这个插件如何使用,先不急着刨根问底,先囫囵吞枣,后面我们配置其他插件的时候,大家看的多了就清楚了,整个结构非常清晰。

** 安装use-package插件
[[https://github.com/jwiegley/use-package][use-package]] 是一个让Emacs配置更加结构化更加清晰的一个宏插件。

#+begin_src emacs-lisp
;; 安装 `use-package'
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

;; 配置 `use-package'
(eval-and-compile
  (setq use-package-always-ensure nil)
  (setq use-package-always-defer nil)
  (setq use-package-expand-minimally nil)
  (setq use-package-enable-imenu-support t)
  (if (daemonp)
	  (setq use-package-always-demand t)))

(eval-when-compile
  (require 'use-package))

;; 安装 `use-package' 的集成模块
(use-package use-package-ensure-system-package
  :ensure t)
(use-package diminish
  :ensure t)
(use-package bind-key
  :ensure t)
#+end_src

2.4 配置quelpa 🔗

quelpa 是配合 package.el 使用的,基于git的一个包管理器。我们在后面会发现,有不少优秀的插件,并没有提交到上面我们设置的仓库源(比如懒猫大大的很多插件),而是在 Github 上或者其他基于 Git 的仓库里,那我们就可以通过 quelpa 来安装这些插件,并且可以与 use-package 结合使用。

** quelpa包管理器
[[https://github.com/quelpa/quelpa][quelpa]] 是配合 =package.el= 使用的,基于git的一个包管理器。
#+BEGIN_SRC emacs-lisp
;; 安装 `quelpa'
(use-package quelpa
  :ensure t
  :commands quelpa
  :config
  :custom
  (quelpa-git-clone-depth 1)
  (quelpa-update-melpa-p nil)
  (quelpa-self-upgrade-p nil)
  (quelpa-checkout-melpa-p nil))

;; `quelpa' 与 `use-package' 集成
(use-package quelpa-use-package
  :ensure t)
#+END_SRC

简单对上面的 use-package 的代码做一个解释:

(use-package quelpa                ; use-pacake 后面跟着的是包的名字,这里是 `quelpa'
  :ensure t                        ; :ensure t 表示需要从仓库源下载这个插件,后面会遇到Emacs内置的插件就是 :ensure nil
  :commands quelpa                 ; 这一行先不用管
  :config                          ; 所有关于这个包的配置,都放到 :config 这个关键词下面
  :custom                          ; 所有这个包相关的变量设置,放到这个部分
  (quelpa-git-clone-depth 1)       ; 相当于在 :config 里配置 (setq quelpa-git-clone-depth 1)
  (quelpa-update-melpa-p nil)
  (quelpa-self-upgrade-p nil)
  (quelpa-checkout-melpa-p nil))

;; `quelpa' 与 `use-package' 集成
(use-package quelpa-use-package
  :ensure t)

2.5 运行org-babel-tangle写入 🔗

配置完成后,需要运行 M-x org-babel-tangle 命令,让代码块都写入到 init.el 里!

2.6 重启Emacs生效配置 🔗

init.el 已经写好了,但并没有生效,需要重启一下Emacs,让Emacs重新加载这个配置文件,才会生效。重启后,Emacs会自动启用 package.el 并会自动安装 use-packagequelpa 等插件。

重启后,你可能会看到下面这样的警告(这是编译时的告警,下次重启就不会再出现了),不用担心,鼠标移动到下面这个窗口并点击(或者按 C-x o 切换到下面这个窗口),然后按 q 键退出这个小警告窗即可。

至此,我们打好了安装插件的基础,我们打好了使用Org mode来管理配置文件的基础,我们对Emacs有了基本的认识,我们的千里之行,又往前走了一大步!

3 结语 🔗

经过今天的学习,你的 emacs-config.org 文件应该长下面这样:

注:在后面的课程里,限于篇幅,不会再贴这个文件的全部内容了,后续我会建一个Github仓库来专门存放配置文件以及每节课后的配置快照。

#+TITLE: Emacs配置文件
#+AUTHOR: Randolph
#+DATE: 2022/12/22 14:23:50

#+STARTUP: overview

* early-init.el
:PROPERTIES:
:HEADER-ARGS: :tangle early-init.el
:END:

在Emacs刚启动,还未加载主要配置文件时的配置文件。

#+BEGIN_SRC emacs-lisp
;;; early-init.el --- Emacs pre-initialization config -*- lexical-binding: t -*-
;;; Commentary:

;;; Code:

;; 设置垃圾回收参数
(setq gc-cons-threshold most-positive-fixnum)
(setq gc-cons-percentage 0.6)

;; 启动早期不加载`package.el'包管理器
(setq package-enable-at-startup nil)
;; 不从包缓存中加载
(setq package-quickstart nil)

;; 禁止展示菜单栏、工具栏和纵向滚动条
(push '(menu-bar-lines . 0) default-frame-alist)
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars) default-frame-alist)

;; 禁止自动缩放窗口先
(setq frame-inhibit-implied-resize t)

;; 禁止菜单栏、工具栏、滚动条模式,禁止启动屏幕和文件对话框
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(setq inhibit-splash-screen t)
(setq use-file-dialog nil)

;; 在这个阶段不编译
(setq comp-deferred-compilation nil)

(provide 'early-init)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; early-init.el ends here
#+END_SRC

* init.el
:PROPERTIES:
:HEADER-ARGS: :tangle init.el
:END:
=init.el= 是Emacs的主要配置文件。

** init.el 文件头
#+BEGIN_SRC emacs-lisp
;;; init.el --- The main init entry for Emacs -*- lexical-binding: t -*-
;;; Commentary:

;;; Code:

#+END_SRC

** package包管理配置
#+begin_src emacs-lisp
(require 'package)
(setq package-archives
	  '(("melpa"  . "https://melpa.org/packages/")
	    ("gnu"    . "https://elpa.gnu.org/packages/")
	    ("nongnu" . "https://elpa.nongnu.org/nongnu/")))

(package-initialize)
#+end_src

** 安装use-package插件
[[https://github.com/jwiegley/use-package][use-package]] 是一个让Emacs配置更加结构化更加清晰的一个宏插件。

#+begin_src emacs-lisp
;; 安装 `use-package'
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

;; 配置 `use-package'
(eval-and-compile
  (setq use-package-always-ensure nil)
  (setq use-package-always-defer nil)
  (setq use-package-expand-minimally nil)
  (setq use-package-enable-imenu-support t)
  (if (daemonp)
	  (setq use-package-always-demand t)))

(eval-when-compile
  (require 'use-package))

;; 安装 `use-package' 的集成模块
(use-package use-package-ensure-system-package
  :ensure t)
(use-package diminish
  :ensure t)
(use-package bind-key
  :ensure t)
#+end_src

** quelpa包管理器
[[https://github.com/quelpa/quelpa][quelpa]] 是配合 =package.el= 使用的,基于git的一个包管理器。
#+BEGIN_SRC emacs-lisp
;; 安装 `quelpa'
(use-package quelpa
  :ensure t
  :commands quelpa
  :config
  :custom
  (quelpa-git-clone-depth 1)
  (quelpa-update-melpa-p nil)
  (quelpa-self-upgrade-p nil)
  (quelpa-checkout-melpa-p nil))

;; `quelpa' 与 `use-package' 集成
(use-package quelpa-use-package
  :ensure t)
#+END_SRC

** init.el 文件尾
#+BEGIN_SRC emacs-lisp

(provide 'init)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; init.el ends here
#+END_SRC