首页
归档
友情链接
关于
Search
1
在wsl2中安装archlinux
307 阅读
2
从零开始配置 vim(15)——状态栏配置
179 阅读
3
nvim番外之将配置的插件管理器更新为lazy
166 阅读
4
2018总结与2019规划
154 阅读
5
wsl 启动报错:Wsl/0x80080005
135 阅读
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
登录
Search
标签搜索
c++
c
emacs
elisp
学习笔记
windows
文本操作术
编辑器
NeoVim
Vim
win32
读书笔记
VimScript
linux
文本编辑器
投资理财
Java
反汇编
OLEDB
数据库编程
Masimaro
累计撰写
474
篇文章
累计收到
33
条评论
首页
栏目
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
页面
归档
友情链接
关于
搜索到
1
篇与
的结果
2026-11-15
《elisp 每日一练》——use-package 入门
之前我们介绍了Emacs的 package 包管理系统,可以进行包的日常维护工作。但是在现在的Emacs中,普通使用的是一个名为 use-package 的包。它专门用来管理我们安装的第三方包,从本篇开始,我们将逐步讨论它的一些相关机制背景知识在早期的Emacs版本中,use-package 还只是一个"编外" 的包,需要通过 package-install 事先下载。但是从 Emacs 29.1 开始它被收编为Emacs内置的软件包,可以直接使用。首先我们要明白一点,use-package 并没有发明一套全新的包管理机制,它是对旧有的包管理系统通过宏进行的封装。底层仍然是 package-install、package-uprade 这样的函数。它的签名如下:(use-package NAME &rest ARGS)使用原版的包管理系统管理包的时候,体验是比较割裂的。我们确认包不是内置的时候,需要先通过编写 (package-install 'name) 这样的代码进行下载,之后再通过 (require 'name) 进行引用, 之后通过代码进行配置和使用。使用 use-package 的一个好处是,它将二者统一起来了,我们只需要写下 (use-package name) 这样的代码,它可以帮助我们完成从下载、更新、引用、配置这样的活。我们仅仅通过use-package 这样一个宏就搞定了。我们按照之前分析 define-minor-mode 的思路来通过展开宏进行分析,看看use-package 背后真正帮我们干了什么。我们先使用最简单的形式:(use-package org)它展开的代码如下:(progn (defvar use-package--warning0 #'(lambda (keyword err) (let ((msg (format "%s/%s: %s" 'org keyword (error-message-string err)))) (display-warning 'use-package msg :error)))) (condition-case-unless-debug err (if (not (require 'org nil t)) (display-warning 'use-package (format "Cannot load %s" 'org) :error)) (error (funcall use-package--warning0 :catch err))))这段代码主要分为两个部分:首先它定义了一个警告函数 use-package--warning0,该函数接受一个关键字和一个err对象。它的作用是将参数格式化,并通过 display-warning 打印。然后通过 display-warning 打印这么一条错误信息。这里我觉得有两点小巧思:这里使用 defvar 定义了一个lambda 函数绑定到变量。而没有使用 defun 直接定义函数。因为 use-package 作为常用的宏,不可能只执行一次。如果使用defun 的方式,就会出现重复定义的情况,而利后缀进行区分的话也没有必要,因为封装的报错函数代码基本雷同。所以这里利用 defvar 定义时只有第一次执行会生效的特性,确保使用 use-package 的不同地方只定义一个报错函数第二点其实算不上什么小巧思,就是这里报错使用 display-warning 而没有使用我们在前面时时常使用的 message 进行调试,或者使用 use-error。首先我们说message 是常规信息输出,用于显示信息。而 display-warning 类似于Emacs中的日志系统。它会往 *Warnnings* 缓冲区中写一条信息。对于这种错误更适合使用日志系统进行记录,方便日后排查。第二部分才是它的重头戏。这里我们可以看到 (require 'org) 加载 org 包的内容。也就是说use-pacakge 此时已经代替了 require。require 的外层经过了严格的异常处理和条件判断。在加载时如果未找到对应的包或者加载时有其他问题,都会使用 display-wwarning 报错,只不过一个是直接报错,而另一个是通过异常处理调用我们事先定义好的函数。从这段分析可以看到 use-package 对 require 外层进行了包装,确保了加载包的错误不会导致Emacs崩溃,影响其他功能的使用。总结本篇我们对 use-package 有了一个基本的认识。知道了它其实就是对 package 系列函数和 require 进行了一层外部封装。将它们有机结合起来,我们可以通过一个use-package 完成包的安装、加载、配置。使代码更加紧凑。
2026年11月15日
1 阅读
0 评论
0 点赞