Skip to content

Latest commit

 

History

History
48 lines (30 loc) · 8.31 KB

ghost.org

File metadata and controls

48 lines (30 loc) · 8.31 KB

The Ghost in Emacs

总论

在这个文档里,我希望记录一些我对于 “为什么是 Emacs ? ” 的思考。我想在这里探讨 “一个好的编辑器(工作环境)是怎样的?” 和 “Emacs 是怎样符合这个要求的?” 。

Emacs 的小而精哲学

小而精

随着配置的深入,我再次深深意识到了 emacs 和 vim 的不同。vim 是一个专注于文本编辑的编辑器,它确实很符合 Unix “只干一件事情并将它干好”的特质,对于“编辑”这一件事情,vim 已经做到很好了。

不过话说回来,难道我的工作只是“编辑文本”吗?显然不是的,为了完成一个项目,需要找灵感,查资料,做设计,团队沟通,代码实现,部署调试,写文档,做展示,发布产品,这期间又伴随着质量检测,版本控制,日程规划等多个事宜。不得不说,vim 或者 vscode 确实可以做一个或者多个工作,比如和代码实现联系密切的文档撰写,版本控制,部署调试都可以在这些现代化的编辑器中完成。不过有一说一,vim 在除了文本编辑外的工作只能说是中规中矩,比较好的优点是 vim 的多模态使得很多功能按键的绑定十分有逻辑。更有很多工作场景是 vim 无所发力的(比如说浏览器,PDF 阅读器,多媒体,团队沟通),这也正是 tmux 或者 i3wm 这样窗口或者桌面管理器存在的意义。我们需要一个管理多个开发工具的工具(比如 tmux 和 i3wm)来协作很多和 vim 一样“小而精”的工具。

那么为什么 vim 要设计成这样,难道不能设计成和 office 软件一样的“大而全”吗?只需要打开一个 word,就可以完成文档撰写,排版,团队批注,多媒体插入等多个功能,这是多么方便的用户体验呀。我觉得是这样的,“小而精”并没有很好概括 Unix 工具的本质特征,它们的本质是 “只干一件事情,并将它干好,并且极其容易与其他工具进行配合” 。在我说的这个前提下,我们假设一个团队的开发力(我瞎编的一个名词,表示一个团队开发软件的功能数)是 100,如果只开发 1 个“大而全”的软件,那么只能开发出具有 100 个功能的软件,而如果平等地开发 5 个“小而精”的软件,并且这些软件极易协作,那么组合起来的功能数则是 (100 / 5)5 = 3200000 个。这会大大丰富用户的功能并且提高定制性和趣味性(突然发现两个看似并不相关的工具居然可以有如此美妙的化学反应)。

工作环境范式

Unix 思想有一个重要的前提是“工具之间极其容易配合”。当然不得不说 Unix 工具是在这个方面做了一些贡献的,基本上所有的工具的输入都可以是 stdin,所有的输出都可以是 stdout,输入和输出内容都是字符串,有管道可以将他们的输入输出联系起来,并且还有许多数据整理工具可以过滤和格式化输入输出。在这个角度上看,Unix 规划的一种工作环境的范式是:“shell + Unix tool”,这种范式,shell (当然还有 tmux 这种终端复用器)负责将多个工具衔接在一起,其他工具负责具体的工作。不过这种范式是没有缺点的吗?当然不是了,shell script 是一个极其糟糕的语言,而且 shell 本质是一个 cli 工具,那么其多媒体表达功能必然会受到限制。

所以在我们普通人的生活中,我们常用“桌面环境 + GUI 工具”的范式,我们用桌面环境来协调多个工具,然后让浏览器,写作软件,编辑器,视频播放器等多个软件满足我们不同的需要。不过用桌面环境的协调真的是一种很好的协调吗?起码就我个人的体验来说,并不是。多个工具的配合一般只有两种方式:

  • 使用复制粘贴:将浏览器文档里的 demo 代码 copy 到编辑器中试试能不能跑;将编辑器中出问题的代码复制到 chatgpt 上问问为啥?
  • 使用人脑:脑子理解了浏览器文档里的内容,想了想再用编辑器写出来;耳朵听了音乐,看着屏幕傻乐,然后敲代码。

当我们再次回顾我们的目标: “只干一件事情,并将它干好,并且极其容易与其他工具进行配合” 。我们会发现我们上面讨论的范式并不让人满意,他们总有或多或少的缺陷,这些缺陷直接导致了我们“工作环境”的不舒适或者 无趣性

Emacs 的宏大

而当我们去看 emacs 的时候,会发现它居然不可思议地符合了“小而精”的哲学。它看上去是一个庞然大物(spacemacs 我甚至需要下载安装十五六分钟),但是他和 word 不同,它的功能都是独立且自由的,每个功能都是小而精的。他之所以看着“臃肿”,正是因为它本质上并不是一个需要“小而精”的编辑器,而是一个组织这些“小而精”工具的“工作环境”,在这点上,emacs 没有对手:

  • 它采用了字符串来处理协作问题,这种最为朴素的方式使得各个插件的协作要求极低。
  • 它使用 elisp 来处理复杂协作问题,这种很学术、规整的语言可以天然抑制与调和编写脚本时的混乱与自由。
  • 它还具有良好的文档(这可能与他们的基础函数基本都支持文档字符串有关,并且设计者有意构建了一个更加秩序化的架构),使得人们很容易探索出多种工具的组合效果。
  • 它还具有友善的社区。我并不知道这是如何发展起来的,我猜测可能是这个社区的人着眼于“工作环境”而非“工具”,所以视角更为宏大;同时对于工具而言,其核心目标是效率,所以很容易到达尽头,而对于环境而言,其核心目标是舒适和趣味,所以引起的讨论会更多。
  • 它还支持 GUI,这点虽然并不是 emacs 原生的,但是不得不说这在某些方面是优于 CLI 工作环境的。

有人将 emacs 比作“操作系统”,我想他们大概是也想表达和我一样的意思。不过操作系统并不只限于满足用户的工作环境需要,它的一部分功能是内核,另一个部分是函数库,这些都是与“工作环境”无关的(起码是侧重点不同的)。我更愿意将 emacs 视作“工作环境和环境里的工具”,和它对标的应该是“Shell + Cli Tool”、“KDE + Chrome + Vscode + Typora + …”。

Emacs 的代码比例

Emacs 项目的代码比例如下:

./img/rate.png

这是一个非常有意思的比例,排名第 1 和第 2 的语言分别是 elips 和 roff ,分别用于“写脚本”和“写文档”,而 C 语言,只占很少的一部分。

当我们从配置 emacs 的角度去思考“解释型语言”和“编译型语言”的差别的时候,我们可以发现,我们可以配置的,可以满足我们定制化需要的,一般都是 elisp ,而那些用 C 语言写成的函数,我们基本上无能为力。

对于 elisp 部分,我们可以用 set 来修改变量,用 advice 来修改函数,用 hook 来管理周期,用 help 来查看文档。一切都是那么得井然有序。而且我个人觉得,elisp 是我见过最简单的语言模型,它没有扰乱语法一致性的“语法糖”,没有复杂甚至恶心的数据类型,没有多态的内存空间,没有奇怪的多线程模型。但是对于 C 部分,反正我是没有为了配置 emacs 动手改过,因为我深知一旦我修改,那么就要面临超级恶心的编译和链接流程了。

这并不是因为 elisp 多么被厚爱或者 C 是一个多么糟糕的设计,造成这种现象的原因是因为两者是不同类型的语言。解释型语言因为有解释器的存在,天生就具备更高级的抽象能力(大部分的复杂性压力可以转嫁给解释器),当有了更加高级、简洁、一致的抽象能力后,语言的设计自然可以设计得轻松、愉快、没有陷阱。而编译型语言需要面对硬件,面对其他二进制文件,天生灵活性就差。

emacs 中 elisp 和 roff 占比如此之高,可以看出其是一个高度定制化的编辑器,这种“定制性”并不是说增设几个可变的选项或者一个漂亮的 settings UI 这么简单,这种定制性是深入 emacs 灵魂的定制性。