1.1 起源:TECO 宏与第一个 Emacs

Emacs 的雏形诞生于 1970 年代的 MIT 人工智能实验室。当时流行的编辑器是 TECO(Text Editor and COrrector),但 TECO 的操作模式是命令式而非实时显示。1976 年,Richard Stallman 与 Guy Steele 等人将 TECO 的宏语言扩展为一系列以“Ctrl”和“Meta”键组合的编辑命令,并为其取名为“Editing Macros”(缩写 Emacs)。第一个 Emacs 实际上是 TECO 之上的宏集合,但它奠定了“实时显示、可扩展”的核心思想。由于 TECO 本身专有且不自由,Stallman 后来决定重写一个完全独立的实现。

1.2 GNU Emacs 与自由软件运动

1984 年,Richard Stallman 启动了 GNU 项目,目标是为类 Unix 系统构建一套自由的软件套件。作为 GNU 的第一批核心组件之一,GNU Emacs 用 C 语言编写底层,用 Emacs Lisp 构建上层功能。1985 年发布的 GNU Emacs 1.0 标志着第一个自由软件编辑器的诞生。Stallman 通过 GNU Emacs 推广了“copyleft”概念,并催生了自由软件基金会(FSF)。此后,GNU Emacs 的版本号从 1 快速迭代至 13,并在 1990 年代成为最流行的跨平台编辑器之一。

1.3 分支与衍生:XEmacs、Aquamacs 等

1990 年代初,由于开发理念分歧,部分开发者从 GNU Emacs 19 分叉出 Lucid Emacs(后更名为 XEmacs)。XEmacs 引入了更现代的用户界面、扩展的 GUI 支持和独立的包管理理念。两派的长期并行发展被称为“Emacs 分裂”。进入 21 世纪后,XEmacs 社区逐渐衰退,GNU Emacs 重新统一了主流用户。此外,针对 macOS 的 Aquamacs(基于 GNU Emacs 并调整了 Mac 原生键位与外观)也成为受欢迎的衍生版。其他较小分支如 Meadow(日文环境优化)也已淡出视野。

1.4 现代发展:Emacs 27/28/29 新特性

2010 年后,GNU Emacs 进入了稳定而持续的版本更新周期。Emacs 27(2020 年)引入了内置的 JSON 解析器、XML/HTML 解析器的改进、以及原生 JSON 序列化支持;同时增加了 HarfBuzz 字体引擎支持,显著改善复杂文本渲染。Emacs 28(2021 年)重点优化了性能:原生 Elisp 编译器(Native Compilation)被集成,可将 Elisp 函数编译为字节码甚至机器码,大幅提升启动和执行速度。Emacs 29(2022 年)加入了纯文本终端下的 True Color 支持、Eglot(内置 LSP 客户端)以及 Tree-sitter 语法解析框架,极大提升了语法高亮与代码导航的精准度。这些新特性使 Emacs 在现代软件开发中依然保持竞争力。

2.1 Emacs Lisp 与解释器

Emacs 的核心不是 C 代码,而是一个嵌入在 C 运行时的 Emacs Lisp(Elisp)解释器。几乎所有功能——从光标移动到打开文件——都是用 Elisp 编写或可通过 Elisp 重写的。用户可以通过 M-x 调用任意 Elisp 函数,或在缓冲区中直接求值代码。GNU Emacs 使用字节码编译器和自 28 版本以来的原生编译器(libgccjit)来提升性能。解释器支持闭包、宏、递归等范式,使得 Emacs 具有了真正的“可编程编辑器”属性。

2.2 Buffer、窗口与框架

Emacs 中,所有可编辑的内容都存在于 Buffer 之中。Buffer 是内存中的文本对象,可以关联文件、目录列表、进程输出等。Window 是显示 Buffer 的屏幕区域,Emacs 可以水平或垂直分割出一个框架内的多个窗口。Frame 则是操作系统级的一个图形或终端窗口,每个 Frame 可以包含多个 Window。这种三层架构允许用户同时查看多个文件、进行多任务操作。

2.3 模式(Mode)系统

2.3.1 主模式与次要模式

每个 Buffer 必须包含一个 Major Mode,它定义了编辑特定类型文件时的行为——例如 text-mode 用于普通文本,python-mode 用于 Python 代码。Major Mode 会设置语法表、缩进规则、快捷键等。此外,一个 Buffer 可以同时激活零个或多个 Minor Mode,它们叠加提供额外功能但不会改变基础编辑行为,例如 auto-fill-mode(自动换行)、flyspell-mode(拼写检查)。Minor Mode 通常通过 M-x 名称启用或禁用。

2.3.2 语法高亮与缩进引擎

Emacs 使用 Font Lock 子系统实现语法高亮。每个 Major Mode 可以定义一系列正则表达式或函数来匹配代码中的不同语义元素(关键字、字符串、注释等),并将其赋予不同的 face(颜色、字体)。缩进引擎则依赖于语法分析:基础模式使用简单的缩进规则,而高级模式如 cc-modepython-mode 包含复杂的解析器,能自动对齐代码块。Tree-sitter 的加入(自 29 版本)让语法分析和缩进更加精确。

2.4 键盘映射与按键序列

Emacs 将每个键盘事件映射到一个命令函数。键映射是嵌套的:例如按 C-x 会激活一个前缀映射,再按 C-f 执行 find-file 命令。用户可以通过 global-set-keydefine-key 修改任意按键绑定。按键序列可以包含修饰键(Ctrl、Meta、Shift、Super、Hyper 等),但默认的 Meta 键通常对应 Alt 或 Esc。由于传统 Emacs 大量使用 Ctrl 组合,用户常面临“Emacs pinky”手指疲劳问题,因此诞生了 Evil(Vim 模拟模式)等替代方案。

2.5 垃圾回收与性能调优

Elisp 解释器使用标记-清除式垃圾回收(GC)来管理内存。当 Emacs 的 gc-cons-threshold 触发时,它会暂停当前执行进行回收,这在高频率操作(如滚屏或语法高亮)时可能引起卡顿。用户可以通过调高阈值(如 setq gc-cons-threshold 100000000)减少 GC 次数,但需注意内存占用。Emacs 28 的原生编译也显著减少了运行时开销。常见优化还包括启用 lexical-binding、使用 use-package 延迟加载、禁用无用 minor mode 等。

3.1 启动与退出(C-x C-c)

在终端输入 emacsemacs & 启动图形界面(如有)。退出时,快捷键 C-x C-c 会提示保存未保存的缓冲区。若想无提示强制退出,可使用 kill-emacs 命令。初次启动默认进入 *scratch* 缓冲区,该缓冲区用于临时编辑和 Elisp 试验。

3.2 光标移动与选择(M-<, C-s 等)

基本移动:C-f 前进一字,C-b 后退,C-n 下一行,C-p 上一行。更快的移动包括 M-f(前进一个单词)、M-b(后退一个单词)、C-a(行首)、C-e(行尾)、M-<(缓冲开头)、M->(缓冲结尾)。选择(标记)通过 C-<SPC> 设置标记点,然后移动光标,被选中区域会高亮显示(称为“区域”)。如需连续选择,可用 C-x h 全选。

3.3 文件管理:打开、保存与 Dired

打开文件:C-x C-f (find-file) 输入路径。若文件不存在则创建新文件。保存:C-x C-s 保存当前缓冲区,C-x s 保存所有缓冲区。Dired(目录编辑)通过 C-x d 启动,它用一个 Buffer 列出目录内容,支持批量重命名、复制、删除等操作,相当于在编辑器内管理文件系统。

3.4 搜索与替换(Isearch、正则表达式)

增量搜索(Incremental Search):C-s 前向搜索,C-r 后向搜索。输入字符时即时跳转并高亮匹配项。按 C-s 重复下一个匹配,按 Enter 结束搜索。替换:M-% 进入 query-replace,输入被替换词和替换词后,每个匹配处可以按 y 替换、n 跳过、! 全部替换。正则表达式搜索使用 C-M-sC-M-%(前者是 isearch-forward-regexp,后者是 query-replace-regexp)。

3.5 撤销与恢复(C-/ 与 C-g)

撤销:C-/(或 C-x u)撤销上一次编辑操作。重复按可继续撤销更早的状态。恢复(反撤销):在撤销后,使用 C-?(或 M-_)可重做被撤销的操作。C-g 是“紧急取消”键,用于中止任何正在进行的命令、退出未完成的选择或抑制递归编辑。如果你不小心按错键,C-g 是万能中止键。

4.1 配置文件:.emacs 与 init.el

Emacs 的启动配置传统名为 ~/.emacs~/.emacs.d/init.el。推荐使用 init.el 文件并置于 ~/.emacs.d/ 目录下。该文件用 Elisp 编写,启动时 Emacs 会自动加载。配置可以定义全局变量、绑定按键、加载包、设置主题等。为了避免单一文件过于庞大,许多用户将其拆分为多个模块并通过 requireuse-package 管理。

4.2 使用 Customize 界面

不熟悉 Elisp 的用户可以通过图形界面进行配置:M-x customize 启动 Customize 分组,点击变量的值可直接修改,并选择“保存设置”将更改写入 custom-set-variables 块(通常位于 init.el 末尾)。Customize 提供搜索、分组和帮助链接,适合非程序员快速调整字体、颜色、缩进等选项。

4.3 编写简单的 Elisp 函数

用户可定义自己的命令。例如,在 *scratch* 中输入:

(defun hello-world ()
  (interactive)
  (message "Hello, Emacs!"))

然后按 C-M-x 求值,即可通过 M-x hello-world 调用。interactive 声明使得该函数可作为命令使用。Elisp 支持条件判断、循环、高阶函数等,是 Emacs 扩展能力的基石。

4.4 包管理器(ELPA、MELPA、NonGNU ELPA)

Emacs 内置包管理器 package.el,默认指向 GNU ELPA(官方仓库)。MELPA 是最大的第三方仓库,包含数千个非官方包。NonGNU ELPA 是 FSF 提供的非 GNU 许可证兼容包的仓库。通过修改 package-archives 可添加 MELPA 等源。使用 M-x list-packages 浏览、安装包,或通过 (package-install 'package-name) 代码安装。

4.5 常见优化技巧:延迟加载、字节编译

延迟加载:通过 autoloaduse-package:defer 关键字,只在需要时才加载包,减少启动时间。字节编译:对 .el 文件运行 byte-compile-file 生成 .elc 字节码,加载速度更快。使用 (elp-instrument-package nil) 可分析性能瓶颈。另外,设置 gc-cons-threshold 为较大值并在 Emacs 启动后再恢复默认值,也是一种常用 trick。

5.1 内置工具:Calc、Org-mode、Gnus、Eshell

Emacs 自带大量应用。Calc 是一个功能强大的 RPN(逆波兰)计算器,支持代数、矩阵、微积分。Org-mode 是 Emacs 的标志性功能,用于笔记、任务管理、日程安排、导出(LaTeX/HTML/PDF)等,被许多人称为“第二大脑”。Gnus 是一个邮件、新闻组和 RSS 阅读器,支持多线程、过滤和多协议。Eshell 是一个纯 Elisp 实现的 Shell,可直接运行系统命令并与 Emacs 缓冲交互。

5.2 娱乐功能:医生、心理学家、俄罗斯方块

Emacs 以“彩蛋”丰富著称。M-x doctor 启动一个模拟心理医生的会话(依拉斯·阿西莫夫风格)。M-x hanoi 显示汉诺塔动画。M-x tetris 运行经典俄罗斯方块游戏。还有 M-x pongM-x snakeM-x solitaire 等。这些内置游戏证明了 Emacs 的“伪装成编辑器的操作系统”特性。

5.3 开发集成:Magit(Git 前端)、Flycheck(实时语法检查)

Magit 是 Emacs 最著名的包之一,提供了直观的 Git 操作界面,能够在不离开 Emacs 的情况下完成添加、提交、推送、分支管理、交互式变基等几乎全部 Git 功能。Flycheck 是实时语法检查器,支持多种语言(Python, C, Ruby 等),通过与外部 linter 配合,在编辑时即时显示错误和警告。

5.4 编辑增强:Yasnippet、Company(自动补全)

Yasnippet 允许用户定义代码片段模板,通过快捷键触发展开。例如,输入 for 再按 Tab 可展开为完整的 for 循环体。Company 是一个可扩展的自动补全框架,支持来自后端(如 company-dabbrevcompany-lspcompany-capf)的补全建议,显示下拉菜单。

5.5 主题与外观:Zenburn、Solarized、Doom Emacs

Emacs 支持通过 M-x load-theme 加载内置主题,或从 MELPA 安装第三方主题。热门主题包括 Zenburn(低对比度护眼)、Solarized(褐色基调)、Doom Emacs(一个预配置的 Emacs 发行版,自带 Doom 主题和大量优化)。Doom Emacs 本身不是主题,但其默认主题 doom-one 深受喜爱。用户也可通过 customize-face 精细调整每个 face 的字体、颜色。

6.1 编辑器圣战:Emacs 与 Vi 的百年恩怨

Emacs 与 Vim(及其前身 Vi)之间的争论是黑客文化中最持久的圣战。Emacs 推崇“将所有工具整合到一个环境”,而 Vim 则坚持“小而精美、专注编辑、模式化操作”。两派用户常以“编辑器宗.教”调侃,网络上充斥着争论、表情包(如“X Emacs is a great operating system, lacking only a decent editor”)。事实上,许多开发者在使用两者之一的经验后,也学会了欣赏另一方的优点,并出现了 Evilm (Emacs vi layer) 等融合方案。

6.2 社区梗:“Emacs 是操作系统”与“Esc-键链”

由于 Emacs 内置了邮件客户端、文件管理器、网页浏览器、Shell、游戏、日历、心理医生等,“Emacs 是操作系统”成为经典调侃。另一个著名梗是“Esc-键链”:传统的 Meta 键在终端中常被模拟为 Esc 前缀,导致用户需要连续按多个 Esc 来正确输入组合键(例如用 Esc Esc Esc 中断操作)。此外,C-h 被吐槽为“帮助键”常被误按,因此有人戏称 Emacs 是“指尖体操”。

6.3 Emacs 会议与贡献指南

Emacs 社区每年举办 EmacsConf(全球线上会议),涵盖从新技术到社区动态的各类演讲。也有 Chicago Emacs Meetup 等线下或本地活动。贡献指南方面,GNU Emacs 使用邮件列表(bug-gnu-emacs)和 git 仓库(savannah.gnu.org)。开发者需签署版权转让协议给 FSF。新手可从小修补(如文档改进、bug 报告)开始,逐步接触 Elisp 核心代码。

6.4 著名用户与轶事

Richard Stallman 自然是 Emacs 的“教父”,他至今仍使用 GNU Emacs 作为主力编辑器。前 Linux 内核维护者 Andrew Morton、知名黑客和作家 Neal Stephenson(使用 Emacs 撰写小说)、Java 之父 James Gosling(曾开发 Gosling Emacs)等都是 Emacs 用户。轶事包括:Stallman 曾因在 Emacs 中添加了“Hello, World”示例与开发者争论;有人用 Emacs 中的 M-x zone(屏保效果)来测试显示器。

7.1 与 Vim 的哲学差异

Emacs 追求“一切皆可编程的集成环境”,而 Vim(及其前身 Vi)强调“键盘效率、模式编辑、通吃一般文本编辑”。Emacs 的启动慢且资源占用高(相比 Vim),但启动后即时可用;Vim 启动快、内存小,但扩展性较弱。Emacs 使用组合键(Ctrl+字母)而非模式切换,Vim 则用 Normal、Insert、Visual 等模式分开。学习曲线方面,Emacs 容易上手但精通困难(因为复杂配置),Vim 初期难(模式切换)但常用操作可快速记忆。

7.2 与 VS Code/Atom 的现代切换者体验

VS Code 和 Atom 是 2010 年代后流行的 Electron 编辑器,拥有丰富的插件市场(通过 JSON 而非 Lisp 配置)、现代图形界面和内置终端。从这些编辑器切换至 Emacs 的用户常惊讶于 Emacs 的古老界面(默认无菜单栏、工具栏)和古怪的键位(如 C-f 而非方向键)。但通过配置 org-mode、Magit、LSP 等,Emacs 可以提供相似的 IDE 体验。对比 VS Code,Emacs 的优势在于高度可编程性(任何操作都可以用 Elisp 重写),劣势在于缺乏原生现代化的 UI 和 Docker 集成。

7.3 推荐场景:适合哪些人群

Emacs 最适合愿意投入时间学习键盘操作、享受深度定制和编程思想的人。它尤其适合以下场景:写 LaTeX/Org-mode 文档、管理复杂项目(通过 Magit 和项目文件)、同时处理多种文件类型(如同时编辑代码、邮件和笔记)。对性能敏感、追求极简启动速度的用户可能更倾向 Vim 或现代编辑器。若你希望拥有“一个环境搞定一切”,Emacs 是最佳选择。

8.1 官方手册与内置教程(C-h t)

Emacs 自带官方教程:C-h t 启动 *Emacs Tutorial*(英语),全程交互式教学,涵盖基本移动、搜索、保存等。官方手册可通过 C-h i 进入 Info 阅读器,选择 “Emacs” 节点查看完整文档。此外,每个命令可通过 C-h k 查看快捷键绑定对应的函数,C-h f 查看函数帮助。

8.2 社区指南与 EmacsWiki

EmacsWiki(emacswiki.org)是最大的社区协作维基,收集了数千条配置技巧、包使用方法和 FAQ。Reddit 的 r/emacs 和 r/orgmode 是活跃的讨论版块。GitHub 上搜索 emacs.d 可找到许多知名用户的配置仓库(如 purcell/emacs.dhlissner/doom-emacs)。中文社区有“Emacs 中国”等论坛。

8.3 常见陷阱:C-g 误按、键位冲突

新手常犯错误:忘记 C-g 可以中断失控的递归编辑;误将 C-x C-c 当作保存(实际是退出);在终端中使用 S-SPC 等组合键失效。键位冲突可能发生在与系统快捷键(如 macOS 的 Cmd+Q)冲突时,需在配置中通过 (setq ns-command-modifier 'meta) 等调整。另外,不要直接在 /tmp 中保存文件,Emacs 的备份文件(~后缀)可能造成混淆。

8.4 如何从零开始配置一个舒适的 Emacs

建议步骤:1)安装最新版 GNU Emacs(macOS 用 brew install emacs-plus,Linux 用包管理器或源码编译)。2)先不配任何文件,运行 emacs -q 体验裸 Emacs。3)阅读内置教程 C-h t。4)创建 ~/.emacs.d/init.el,安装 use-package 然后逐步添加包:Magit、Company、Flycheck、Yasnippet、某个主题。5)使用 (setq inhibit-startup-screen t) 关掉启动页面。6)开启 (global-linum-mode t) 显示行号。7)尝试 Evil 如果向往 Vim 键位。8)定期备份配置,并参考成功案例进行迭代。勿贪多求全,优先满足日常工作流即可。