关注了就能看到更多这么棒的文章哦~
Mastering Emacs
By Jake Edge
August 30, 2023
ChatGPT assisted translation
https://lwn.net/Articles/942962/
一连串的偶然事件,其中一些导致了棘手的问题( https://projects.csail.mit.edu/gsb/old-archive/gsb-archive/gsb2000-02-11.html ),使得我接触到了一本名为《Mastering Emacs》的书。其实我已经在工作中使用 Emacs 编辑器超过 16 年了,而且早在上个世纪就开始研究它,因此我应该对这个编辑器兼操作系统非常熟悉。然而,出于各种原因,情况并非如此,不过这本书以及一些专注的调查帮助我走上了 Emacs 启蒙之路。《Mastering Emacs》也可能会帮助其他那些在 Emacs 文档的汪洋大海中苦苦挣扎的人。
我之所以会进入这个领域,背后的故事有点滑稽。这些困难有时候看起来很有意思……当然,它们确实很好笑,但失去的“生产力”可能会成为问题。无论如何,前几周,Hacker News 上有一篇关于“Elixir for cynical curmudgeons”的文章引起了我的注意,因为我显然符合这一描述。阅读了这篇文章并查阅了 Elixir(以及 Erlang)文档后,我想起自己一直想更好地理解 Lisp 宏,或者其实我根本不懂 Lisp 宏。这让我重新捡起了一个项目,这是之前我在 linux.conf.au 上听了一个我非常喜欢的关于 Lisp 历史的演讲后开始启动的项目,尽管我后来放弃了。
这个项目本质上是一个 Lisp 解释器。是用 Python 编写的,充其量只完成了 5%——而且可能不会有更多进展了。但我重新整理了一下,让它可以处理更多的 Lisp construct,然后突然意识到,我对 Lisp 的了解甚至不足以开始做这些事情。这应该是一个可以解决的问题,于是我寻找了更多的 Lisp 知识,然后发现了《A Road to Common Lisp》。其中就包含了一些建议,有一些我开始采纳,但后来在命令行中使用 Lisp 时遇到了一些烦恼。于是就不可避免地开始转向 SLIME。
当然,既然 SLIME 也被称为“Emacs 可用的更好的 Lisp 交互模式”,这就让我来到了 Emacs,这是我每天都在工作中愤怒地使用的编辑器。但它不是我的首选编辑器;自上世纪 80 年代初以来,我一直在使用 vi(及其变种),并且在工作相关任务之外,只是不在工作中使用。当我 2007 年全职加入 LWN 时,首日的惊喜就是发现 Emacs 与这个网站运营密切相关(特别是用在文章编辑方面)。于是我进行了很多 Emacs 速成学习,才能应付工作,至今一直都这样——不管是好是坏。
事实上,我不是任何编辑器的“高级用户”;我怀疑我仍然可以完全正常地使用我学过的那个伯克利 Unix 版本的 vi,那是我多年前使用的。我可能只是涉猎了其中一些功能,因为我不反对采用粗暴的方法解决编辑问题。但多年来,我掌握了更多的 Emacs“技巧”,并且对它所能做的一切都感到印象深刻。一直让我感到好奇的是,它可以使用 Lisp 进行转化(transmogrified)。
显然,Vim 也有一些附加 add-on 可以达到类似 SLIME 的效果,所以我也可以选择这个路径,但 Emacs 似乎是正确的选择。我可以以一种奇怪的方式坚持自己的做法,比如忽略 Evil 模式(给 Emacs 提供了类似于 vi 的体验)。我对 Emacs 的第一次尝试中记住的一点点东西——使用上世纪 80 年代中期的 GNU Emacs 手册,基本上只有 Control-x Control-c,简记为 C-x C-c,用来退出,这些都一直在我脑海中留存,所以我决心在 2007 年的速成课程以及之后的时间里继续走这条道路。
The book
当我开始使用 SLIME 时,我意识到我对 Emacs 的一些重要基础知识了解不足。之前我曾了解过《Mastering Emacs》,考虑购买,但在购买前被其他事情分散了注意力。《Mastering Emacs》网站本身就是一个很好的资源,我曾经访问过。就在我开始研究 SLIME 的时候,Hacker News 上有一篇关于这本书的帖子;当我看到在帖子的评论中提到这本书在打折时,我果断购买了它。
除了“浪费”的时间外,我完全没有后悔购买。Mickey Petersen 在这本书中做得非常出色,我认为它完全值得其原价($49.99)。我仍在努力逐渐阅读它,而且无疑会经常参考它。它提供 PDF 和 EPUB 两种格式;没有纸质版本。Petersen 在他的网站上详细介绍了书的写作过程(当然是在 Emacs 中完成的),他还聘请了一位专业编辑来帮助他,这是一个不错的举措。他网站上的文章写得很好,所以也许他的编辑没有太多工作要做。
这是一本充满观点的书,而且理所当然。在 Emacs 中干巴巴地尝试各种选项和可能用法,远远不如读这本书有用。这并不是说 emacs manual 没有用处,毕竟在用 Emacs 时就很方便,但 Petersen 提供了一种 Emacs 的导览,以一种清晰讲述的方式来描述编辑器的各个部分,而不是作为参考资料。在这个过程中,他清楚地表明了他的观点、为什么有这些观点、以及这如何改变了他的 Emacs 环境。然而,并没有期望读者严格遵循他的建议;我采纳了一些他的建议,放弃了其他一些,并且我进行了一些自己的自定义设置。但这些都不会以任何方式干扰书的其他部分。
初看起来这本书的组织结构可能看起来有点奇怪,但我现在越来越喜欢它。除了介绍性材料之外,他从 Emacs 的哲学开始,这是一个重要的基础。理解“Emacs 是一个发烧友的编辑器”是使用它的基础。他指出,其中许多发烧友相关的事情就是需要学习一些 Emacs Lisp(elisp),这让一些潜在的用户感到害怕并远离,有点可惜。
这本书对于“为什么选择 Lisp?”有一个很好的解释,这一点深深地触动了我。一个没有代码和数据区别的语言将是 Emacs 及其生态系统的基础,这很有道理。显然,我进一步深入研究 Lisp 的兴趣使我很容易接受这种解释;其他人可能不会觉得这么有吸引力。
Terms
“重要约定(Important Conventions)”部分在 Emacs 术语和其他地方使用的术语之间有很好的帮助和过渡。诸如“window”、“frame”、“mark”、“point”、“buffer”、“kill”、“yank”等术语都是 Emacs 中有特定含义的;其中一些令人困惑,因为跟当前的用法是有冲突的。Emacs 在其他用法出现之前就开始使用这些术语,但它当时并不流行或可见,无法“强制”让后续类似作品都按它的来。
该部分还描述 buffer 界面、modeline 以及 mini-buffer。buffer 是 Emacs 中的交互基本单位,可以在 window 中显示,包含在 frame 中。当然,现在操作系统中人们常说的 window 其实是另一个不同的含义,通常对应于 Emacs 名词中的 frame。buffer 可以有一个 major mode 和多个 minor mode。理解所有这些术语非常重要,但到这时候,这本书还没有开始讨论如何安装或启动 Emacs。
当然它会介绍如何安装和启动 Emacs,并且建议读者运行最新的可用 Emacs,当时是 Emacs 28;此后,Emacs 29.1 发布了。Petersen 有一篇长篇文章,对 Emacs NEWS 文件中他比较感兴趣的功能给出了说明,这可能是为了不久之后更新《Mastering Emacs》的准备。购买了这本书的人可以免费获得这些更新。
可以猜想接下来要讲的就该是如何编辑文本,但实际上,在这本书的 300 多页(中间位置)之后才会介绍这部分内容。在那之前,会详细描述 Emacs 使用的按键序列(key sequence),对于新手来说,这确实是需要掌握的领域。Petersen 提出的最强烈的观点之一是将 Caps Lock 键重新映射为 Control 键;实际上,他建议禁用左侧的 Control 键(到目前为止我还无法采用这最后一步,因为有几十年的肌肉记忆需要克服)并且将该键重新映射为 Meta 键(另一个主要的 Emacs 组合按键),这个做法对大家来看可能有些疯狂。
书中详细描述了通用的自定义界面(M-x customize);它允许更改令人难以置信的大量选项。这些改动可以仅用于当前会话(session),也可以保存在启动文件中(通常是~/.emacs.d/init.el 这种,当然,~/.emacs 也仍然有效),以使它们变得永久生效。自定义界面是我在 Emacs 中遇到的少数几个具有按钮和其他控件的界面之一,这对于使用鼠标而不是键盘的人来说似乎是正确的方式。
在互联网上搜索“在 Emacs 中如何做 X”将迅速引导你前往许多不同的地方,提供质量良莠不齐的各种建议和想法。它们通常需要对 elisp 代码进行 evaluate (运行),这很容易做到,但我有点弄不清楚这跟当前运行中的 Emacs session 有什么关联。Petersen 就马上介绍了 M-x eval-region(和 eval-buffer),但建议将代码放入启动文件中,并在出现问题时重新启动 Emacs(听起来有点吓人)。Petersen 在他的 elisp evaluation 的文章中更全面地介绍了这些做法。
到目前为止,我真的没有在对代码进行 evaluate 的过程中遇到什么不可解释的主要的困难,可能我过于担心了。我肯定不想经常重新启动 Emacs;一旦 buffer/window/frame 都按我喜欢的方式设置好了,那么很不愿意再重新来做这一切。也许有一些用于保存和恢复状态的软件包;事实上,不太可能没有这些软件包。但这是今后要做的事情了。
Help, movement, and editing
Petersen 介绍了 Emacs 中广泛使用的帮助系统,他说他经常使用。我非常赞同,要想知道如何找出一个键的作用是什么,或者一个命令的绑定键是什么(如果有的话),以及一个命令的作用等等,都是非常有用的。Emacs manual 总是可用的,还有 GNU 系统许多其他部分的 info 文档、man 文档等等。我打算弄清楚 EPUB 阅读工具,以便将来在使用 Emacs 时可以参考这本书。
但是等等,还有更多。下一个主要部分是“移动理论”,它涵盖了诸如加载和保存文件(或在 Emacs 术语中所说的 find file 以及 save buffer)、在 buffer 之间切换、列出所有 buffer、关闭 buffer 等内容。他强烈建议将 C-x C-b 这个查看 buffer 列表的命令改为使用 M-x ibuffer。他还认为 C-x b 切换 buffer 的命令可以有更好的自动完成功能,因此他建议改用 IDO 模式(或在 Emacs 27+中使用 FIDO 模式)。
当然,在 Emacs 中有无数种移动 point(也就是光标)的方法:按字符移动、按行、按单词、按 s-expression、按页、按段落、向前、向后,可能还有反向移动。鼠标可以使用(至少在 GUI 窗口中的 Emacs 中可以),方向按键也可以使用。后者在某种程度上让我陷入了困境,尽管 Petersen 对“cheating”方式非常乐观;我希望能够训练自己不使用这种方式,但也不打算禁用(或重新绑定)这些键。
最后,我们来到编辑相关章节(跳过了很多内容才到达这里)。其中强调的一点是,“killing”文本是从 buffer 中清除文本的主要方式,但这个 kill 动作与大多数编辑器中的概念明显不同。除了单个字符的删除命令(可以向前和向后),几乎所有其他删除文本的方式都是通过“kill”文本并将其移动到 kill ring 中来实现的。也就是说,kill ring 存储了所有这些删除动作,以便它们可以被“yanked”(粘贴)到 buffer 的其他位置,或者完全粘贴到其他 buffer 中。
与书中的其他部分一样,Petersen 描述了这些功能的实际应用,并试图指导读者如何充分利用它们。例如,可以使用 region mark 命令选择一个包含了三个单词的区域(在 Emacs 术语中 region 就是在 mark 和光标之间的这部分内容),然后删除它,但简单地执行三个 M-d 命令来按单词删除会更快;连续删除的话会追加到同一个 kill buffer 条目中,因此效果完全相同。正是这些分散在整本书中的小贴士使得它如此有用。
当然,记住这些小贴士、命令、按键序列就会很困难。自从完成了速成课程以来,我一直在维护一个 emacs-cheat 文件,最近在用 vi 精心维护。在过去的几周里,它已经迅速增长。我发现自己经常需要打开它(当然是在 Emacs 中)做参考,但有希望我实际上已经将学到的一些东西记在了肌肉记忆中。时间会证明。
到目前为止,我已经阅读了书的三分之二,同时略读和挑选了其余的部分。也许我对 Emacs(Lisp,…)的新发现热情使我的判断有所偏颇,但我发现这本书真是令人惊叹。在某些地方我有一些小小的不同意见;例如,他建议的 whole-line-or-region 包可以很容易地安装,只要你像他建议的那样添加了 MELPA 存储库,但他从未提到你需要在 init.el(或其他位置)中启用这个软件包。
与此同时,似乎 MELPA 是大多数 Emacs 包的存放地,所以为什么不默认添加它呢?这当然不是 Petersen 的错;我应该向我的发行版或 Emacs 项目本身提出这个问题。(啊,事实证明,Richard Stallman 反对 MELPA,所以我想我应该向我的发行版提出问题,或者干脆忽略这个问题并继续前进。)
哪怕在我阅读过了的部分中,我也没有在这篇文章中讲述全部内容,比如:undo ring、包管理器、搜索、tab 等等。请注意,阅读这本书可能会占用很多时间,尝试应用所学的知识也可能会占用你很多时间。我发现自己比以前更经常停下来,但也确实在 Emacs 中可以更高效地移动光标了;到目前为止,很难看出整体来说是否提高了效率,但看起来很有希望。我的 emacs-cheat 文件(始终在另一个 window 或者叫 frame 中是打开的)是按照我的大脑(据称)工作的方式组织的,所以对其他人来说,沿着这个方向采用一些个性化的做法可能是有意义的。
当我沿着这条充满兔子洞(译者注:各种意外惊喜)的路径摸索时,我并没有打算要写一篇文章,但当我深入了解了这本书,似乎读者也可能想了解一些信息。目前,我的目标是看看我是否可以戒掉 vi,相当于是作为一种测试方式;我当然对 vi 编辑器没有任何意见,以后也还会使用它。例如,我甚至没有尝试在终端中或通过 SSH 使用 Emacs,这些情况可能需要暂时回到我的最熟悉的编辑方式上去。与此同时,我正在享受探索 Emacs(和 Lisp)的过程,学习新东西总是很有趣的。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~