跳转到内容

GNU Emacs — 一个伪装成编辑器的 Lisp 操作系统

待复核

想象一台游戏主机:你买的时候它就能玩几个自带游戏(文本编辑),但真正厉害的是它有一套完整的游戏开发引擎内置在里面——你可以在这台主机上给自己写新游戏(邮件客户端、文件管理器、Git 界面、RSS 阅读器),而且写完不用重启,直接就能玩。这台”主机”就是 Emacs,那个内置的”游戏引擎”叫 Emacs Lisp。

GNU Emacs 是 Richard Stallman 在 1984 年启动的自由软件项目,表面上是一个文本编辑器,实际上是一个用 C 写的 Lisp 解释器,碰巧自带了一套文本编辑功能。它的 src/ 目录里大约 35 万行 C 代码实现了一个完整的 Lisp 运行时(求值器、垃圾回收器、字节码虚拟机),以及显示引擎和平台抽象层。在这个运行时之上,lisp/ 目录里超过 100 万行 Emacs Lisp 代码定义了你看到的一切——从光标移动到语法高亮到内置的俄罗斯方块游戏。

Emacs 的官方定义是”可扩展、可定制、自文档的实时显示编辑器”。这里最关键的词是自文档——每一个函数、变量、按键绑定都自带文档字符串,你可以在运行中按 C-h f(查函数)或 C-h v(查变量)即时查看任何内部状态。整个编辑器对你是透明的。

不理解 Emacs 的设计思路,下面这些现象没法解释:

  • 为什么 Emacs 用户说”我不用编辑器,我住在 Emacs 里”——它能收发邮件(Gnus)、管理日程(Org Mode)、编写论文(AUCTeX)、做项目管理(Org Agenda),确实可以当操作系统用
  • 为什么 Org Mode 被学术圈和 GTD 社区视为最强大的纯文本笔记/任务系统——它不是一个独立软件,而是 Emacs Lisp 生态里长出来的杰作
  • 为什么 VS Code 的插件 API、Neovim 的 Lua 脚本、甚至浏览器的 DevTools 都在重新发明 Emacs 40 年前就有的东西——用脚本语言驱动编辑器的范式源头就是 Emacs
  • 为什么 Vim 和 Emacs 的”圣战”从 80 年代吵到现在——它们代表了两种根本不同的哲学:Vim 追求”最少按键编辑文本”,Emacs 追求”在一个 Lisp 环境里做一切”
  • 为什么 Ctrl+A(行首)、Ctrl+E(行尾)、Ctrl+K(删到行尾)这些快捷键在 macOS 终端和几乎所有 Unix shell 里都能用——它们就是 Emacs 按键绑定,被 readline 库继承后散布到了整个 Unix 世界

Emacs 的设计可以拆成三根支柱(先记人话,源码文件名可后看):

1. Lisp 解释器是内核,编辑器是应用。 大多数编辑器是「C/C++ 写编辑核心,插件 API 暴露有限能力」。Emacs 反过来:C 层只提供最底层原语(内存、显示、系统接口),几乎所有用户可见行为都用 Emacs Lisp 实现。你按下一个键,C 层捕获事件后立刻交给 Lisp 求值器。用户和核心开发者用同一种语言、同一套 API——没有「插件能做」和「核心才能做」的鸿沟。

2. Buffer 是万物容器。 Buffer 不只是「打开的文件」。它可以显示文件、shell 输出、编译日志、邮件、网页、甚至图片。所有 buffer 共享同一套文本操作 API,所以你在文件编辑里学会的操作,看日志、读邮件时一模一样适用。

3. 自文档是强制基建。 每个 defun / defvar 都该带文档字符串。C-h 是帮助入口——C-h k 查按键、C-h f 查函数、C-h v 查变量。Emacs 因此成为自己的参考手册,不必离开编辑器查文档。

想对照源码时,可以按三层扫一眼(跳过也不影响跟案例):

  • C 运行时src/lisp.hLisp_Objecteval.c 求值、alloc.c GC、bytecode.c 字节码;Emacs 29+ 还有 comp.c(libgccjit 本地编译)。
  • 显示引擎xdisp.c 把 buffer 变成字形矩阵,dispnew.c 做差分重绘;平台代码在 xterm.c / nsterm.m / w32term.c / term.c
  • Lisp 应用层lisp/simple.elfiles.el 等;Major Mode(如 python-modedired-modegnus)决定 buffer 行为。

主循环一句话:捕获输入 → 查按键绑定 → 跑 Lisp → 改 buffer → 重绘。

案例 1:在运行中修改编辑器行为

Section titled “案例 1:在运行中修改编辑器行为”

你想让 C-c d 插入当前日期。不需要重启 Emacs,不需要修改配置文件,直接在任何 buffer 里写:

(global-set-key (kbd "C-c d")
(lambda ()
(interactive)
(insert (format-time-string "%Y-%m-%d"))))

选中这段代码,按 C-x C-e(eval-last-sexp),立刻生效。现在按 C-c d 就会插入 2026-06-24。这就是”Lisp 解释器是内核”的实际体验——你在编辑器运行过程中直接修改它的行为,不用编译、不用重启、不用等插件加载。

你不确定 C-k 做什么:

C-h k C-k

Emacs 弹出帮助 buffer,告诉你:C-k 绑定了 kill-line,功能是删除从光标到行尾的内容,并列出这个函数定义在 simple.el 的哪一行。你可以点击源码链接直接跳过去阅读实现——一个用 Emacs Lisp 写的函数,读起来和你自己写的配置没有区别。

* TODO 学习 Emacs 基础按键 :学习:
DEADLINE: <2026-06-25>
** DONE 完成 tutorial :学习:
CLOSED: [2026-06-24 Tue 14:00]
** TODO 配置 init.el
* 读书笔记
用 =C-c C-t= 切换 TODO 状态

Org Mode 把纯文本变成了带折叠、带日期、带标签、可导出 PDF/HTML 的笔记系统。它不是一个独立应用——它就是一个 Emacs Major Mode,底层全是 Emacs Lisp,所以能和 Emacs 的其他一切无缝集成:你可以在 Org 文件里嵌入代码块并直接执行(Babel),可以从 Org Agenda 跳到任意文件的任意行。

  1. 按键让手指打结:Emacs 大量使用 CtrlMeta(Alt)组合键,C-x C-f(打开文件)、C-x C-s(保存)、C-x C-c(退出)。新手前三天会觉得小拇指快断了。解决办法是把 Caps Lock 映射成 Ctrl——这是 Emacs 社区几十年的标准建议。或者用 evil-mode 获得 Vim 按键体验。

  2. 配置即编程,起步门槛高:Emacs 的配置文件 ~/.emacs.d/init.el 是一段 Emacs Lisp 程序。不懂 Lisp 就不会配置,不会配置就用不顺手。建议从 Doom Emacs 或 Spacemacs 这类预配置发行版入手,等熟悉后再逐步替换成自己的配置。

  3. 默认界面劝退:原版 Emacs 启动后有菜单栏、工具栏、启动画面,看起来像 2003 年的软件。很多人第一眼就关了。实际上加三行配置就能变干净:(menu-bar-mode -1) (tool-bar-mode -1) (scroll-bar-mode -1)

  4. Emacs Pinky(Emacs 小指病):长期大量使用 Ctrl 组合键真的会导致小指酸痛。除了重映射 Caps Lock,还可以考虑 which-key(提示可用按键)减少记忆负担,或者干脆用 evil-mode 切到 Vim 的模态编辑。

适用

  • 你想要一个”用一辈子”的工具,且愿意花几个月适应——Emacs 的核心按键和 Lisp 接口 40 年没变过,学习投资不会过期
  • 你的工作流跨越编程、写作、笔记、邮件、任务管理——Emacs 能把这些全部统一在一个界面和一套操作逻辑里
  • 你想深入理解”可编程环境”意味着什么——没有比 Emacs 更极端的例子了
  • 你对 Lisp 感兴趣——Emacs 是目前最大的、活跃维护的 Lisp 代码库,也是学 Lisp 最实用的入口

不适用

  • 你只想写代码,不想折腾配置——VS Code 开箱体验远好于原版 Emacs
  • 你需要和团队统一开发环境——Emacs 的配置高度个人化,很难标准化分发
  • 你追求极致的纯文本编辑效率——Vim 的模态编辑在单纯的文本操作上比 Emacs 的组合键更快(但 evil-mode 可以两全)
  • 你需要现代 GUI 集成——Emacs 的图形界面虽然能显示图片和 PDF,但和 VS Code 或 JetBrains 的 GUI 体验不在一个时代
  • 1976 年:Richard Stallman 和 Guy Steele 在 MIT AI Lab 为 ITS 操作系统写了初代 EMACS(Editor MACroS),它不是一个编辑器,而是一组宏——运行在 TECO 编辑器之上的宏集合。名字就是”编辑器宏”的意思。
  • 1984 年:Stallman 启动 GNU 项目,GNU Emacs 是第一个发布的组件。这一版从头用 C 写了一个 Lisp 解释器作为内核,不再依赖 TECO。这个架构决策定义了之后 40 年的 Emacs。
  • 1991 年:XEmacs 从 GNU Emacs 分叉,两个版本竞争了十多年。XEmacs 最终在 2009 年后停止活跃开发,GNU Emacs 成为唯一主线。
  • 2003 年:Org Mode 由 Carsten Dominik 创建。最初只是大纲笔记工具,后来演化成可能是 Emacs 生态里最有影响力的包——很多人为了 Org Mode 而学 Emacs。
  • 2016 年:Emacs 25.1 发布,引入动态模块支持,允许用 C 写可加载模块——四十年来第一次对 Lisp 之外的扩展方式开了口子。
  • 2023 年:Emacs 29 发布,集成 Eglot(内置 LSP 客户端)和 Tree-sitter,这是对现代编辑器标配功能的正面回应(开发工作在 2022–2023 推进)。
  • 持续至今:Emacs 的开发节奏很慢(一个大版本通常 2-3 年),但从未中断。邮件列表 emacs-devel 是主要开发沟通渠道,不用 GitHub PR。

一个够用的 ~/.emacs.d/init.el,让默认 Emacs 变得可用:

;; 关掉视觉噪音
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(setq inhibit-startup-screen t)
;; 基础编辑体验
(setq-default indent-tabs-mode nil) ; 空格代替 tab
(setq-default tab-width 4)
(global-display-line-numbers-mode 1) ; 行号
(electric-pair-mode 1) ; 自动配对括号
;; 搜索增强
(setq isearch-lazy-count t) ; 搜索时显示匹配数
(fido-vertical-mode 1) ; 内置模糊补全(Emacs 28+)
;; 自动保存和备份放到一个目录,别在项目里撒 ~ 文件
(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))

这 12 行配置不装任何第三方包,就能让 Emacs 从”2003 年界面”变成一个干净、现代的编辑器。之后想要更多功能,再逐步加包。

  1. “把解释器当内核”是终极可扩展架构:Emacs 证明了如果你的编辑器本质上是一个语言运行时,那用户和开发者之间的能力差距就消失了——任何人都能改变编辑器的任何行为,用的是和核心开发者一模一样的 API。VS Code 的插件 API、Neovim 的 Lua 绑定都在不同程度上追求这个目标,但 Emacs 从第一天就做到了最彻底的版本。

  2. 自文档是可维护性的基础设施:强制每个函数和变量带文档字符串,加上运行时随时可查的帮助系统,让 Emacs 成为自己的参考手册。这个思想在现代软件里演化成了 JSDoc、Python docstring、Rust 的 /// 注释——但很少有系统像 Emacs 一样把”查文档”做成一个按键就能触发的内置体验。

  3. Buffer 抽象的复用威力:把一切内容(文件、进程输出、网页、邮件)统一放进 buffer,用同一套文本操作 API 处理。这和 Unix 的”一切皆文件”是同一个哲学——统一抽象减少认知负担,让已学技能可以迁移。

  4. 40 年的兼容性靠的是稳定内核:Emacs Lisp 的核心 API(defun、setq、buffer 操作函数)从 80 年代到现在几乎没变。用户 1990 年写的配置代码今天还能跑。这种长期稳定靠的不是”不改”,而是”只在 Lisp 层演进,C 层保持最小接口”。

  5. 社区驱动的慢迭代也能活 40 年:Emacs 没有商业公司支持,开发用邮件列表而不是 GitHub,发版周期以年计。但它从未中断过开发。这说明开源项目的生命力不一定来自快速迭代,也可以来自稳定的架构和忠诚的用户群。

  • 官方教程:在 Emacs 里按 C-h t 启动内置 Tutorial,交互式学完基本操作
  • 入门书:Mastering Emacs (Mickey Petersen)(最实用的现代 Emacs 入门)
  • 预配置发行版:Doom Emacs(Vim 按键 + 现代包管理,开箱即用)
  • Org Mode:Org Mode 官方手册(Emacs 生态的杀手级应用)
  • vim —— Emacs 的宿敌,走”模态编辑”路线而非”Lisp 环境”路线
  • neovim —— Vim 的现代分叉,用 Lua 走了 Emacs “脚本语言驱动编辑器”的同一条路
  • vim —— 编辑器圣战的另一方:Vim 追求”最少按键编辑文本”,Emacs 追求”用 Lisp 构建一切”。evil-mode 把 Vim 的模态编辑完整搬进了 Emacs,Doom Emacs 和 Spacemacs 都默认启用——很多”Emacs 用户”的日常操作和 Vim 用户一模一样
  • neovim —— Vim 的现代化重写,内置 Lua + LSP,和 Emacs 29+ 的能力越来越接近
  • kakoune —— “先选后做”的模态编辑器,和 Emacs 的组合键操作形成对比
  • lite-xl —— 同样走”C 核心 + Lua 脚本”架构,但追求极简而非大而全
  • atom —— Atom — Web 技术做桌面编辑器的先驱
  • doom-emacs —— Doom Emacs — 启动不到一秒的模块化 Emacs 配置
  • geany —— Geany — 用 C 写的轻量级 GTK 编辑器
  • joplin —— Joplin — 开源 Evernote 替代
  • logseq —— Logseq — 块结构离线知识库
  • lunarvim —— LunarVim — 开箱即用的 Neovim IDE 发行版
  • spacemacs —— Spacemacs — 让 Vim 党和 Emacs 党握手的编辑器配置
  • texstudio —— TeXstudio — LaTeX IDE
  • textmate —— TextMate — macOS 上定义 bundle 宏系统的编辑器
  • xi-editor —— xi-editor — 异步架构编辑器的先驱实验