暗无天日

=============>DarkSun的个人博客

读:为什么我在终端里待了十年——一个 Emacs 用户的 GUI 观察

Alcides Fonseca 最近写了篇文章 Why TUIs are back,说终端界面(TUI,Terminal User Interface)正在复兴。他举了 DHH 的 Omarchy 作为例子,说那个系统里三种界面之一就是 TUI。我看完之后的感受是:这说的不就是我吗?

说起来我有资格聊这个话题。2017 年我有一台跑不动图形界面的老 ThinkPad X41,干脆就在纯字符终端下用了很长时间,收发邮件、浏览网页、听音乐、看视频、看 PDF、管文件全在终端里(详见我的 Linux 终端工具)。后来换了能跑图形界面的机器,主力编辑器还是 Emacs,日常自动化靠 shell 脚本,写代码用 Claude Code,大部分时间还是在终端里。不是我觉得 TUI 有多酷,是真的回不去了。

GUI 怎么把自己搞砸的

Fonseca 的文章梳理了三大平台的 GUI 框架历史。看完只有一个感觉:GUI 框架换得比手机还勤,每换一次就丢点东西。

Windows:从 MFC 到 MAUI,换了一茬又一茬

Windows 的 GUI 框架史就是一部推倒重来的流水账。1992 年 MFC 封装 Win32,然后是 OLE、COM、ActiveX,再后来 WinForms、WPF、Silverlight、WinUI、MAUI。PowerShell 之父 Jeffrey Snover 说过,这些框架的复杂程度,比最晦涩的哲学书还难啃。

问题不只是复杂。每次推倒重来,新框架总会丢掉旧框架的一些能力。Domenic Denicola 总结过:Windows 原生开发是个烂摊子,每个新框架都有缺口,旧框架能做的事新框架做不到。结果就是企业桌面应用干脆不跟了,Electron(用网页技术做桌面应用的框架)成了默认选择。

Linux:设计上就注定分裂

Linux 的 GUI 分裂是写进基因的。GTK 和 Qt 两套框架各干各的,虽然都能跑在对方的桌面环境里,视觉上始终是"凑合能看"的状态。而且 Linux 发行版 × 桌面环境 × 硬件的组合太多了,大多数商业公司根本不做原生 Linux 应用,要么用 Electron 一把梭,要么让开源社区自己搞。

作为一个 Linux 桌面用户,我对这种分裂有切身体会。装个应用,它可能用 GTK,也可能用 Qt,还可能是 Electron。三个应用的菜单栏长得不一样,快捷键不一样,右键菜单不一样。习惯了这种不一致之后,回到终端反而觉得踏实:所有程序的快捷键都是同一套(Ctrl-C 退出、Tab 补全、上下箭头翻历史),行为是可预测的。

macOS:从一本圣经到无政府状态

Apple 曾经是 UI 一致性的标杆。Human Interface Guidelines(人机界面指南)被全世界的 UI 课程引用,Xerox PARC 和 Apple 分别定义了"好的用户界面"应该长什么样。

几十年过去了。Apple 自己开始无视 Fitts 定律(一个关于"目标越大越容易点到"的界面设计原则),把窗口调整按钮做得越来越小,给每个菜单塞图标。macOS 不再是设计师的避风港。

Fonseca 的原文有一句说得挺到位:"当每个应用长得都不一样的时候,如果你在做艺术(包括游戏),那是好事;如果你只是想让用户把活干完,那就是灾难。"

Electron:无奈的妥协

大家都知道 Electron 应用吃内存。Fonseca 说的更具体:他的 Dock 栏里 14 个应用,8 个原生、6 个 Electron(Slack、Discord、VSCode、Cursor 等)。但他最受不了的不是内存,是键盘工作流一团糟。

他举了 Cursor 的例子:你在 agent 面板里写完需求,想切到侧边的 agent 列表,纯键盘能做到吗?能归档一个 agent 吗?在原生 macOS 应用里,这些操作都有标准快捷键,而且在菜单栏里显示。Electron 应用里,快捷键有没有、是什么、跟系统习惯一不一致,全看开发者心情。

过去十年,Electron 开发者越来越倾向于不给操作加菜单栏入口。因为这些应用本质上是在沙箱里跑网页,开发者忘了(或者根本不知道)原生应用该有的交互规范。

Slack 是这里面做得最好的,但也不完美。作为一个终端为主、偶尔切到浏览器查资料的人,我倒不太受这个罪。但每次从 Emacs 切到浏览器,复制粘贴的快捷键还好,想用 Ctrl-A 跳到行首却发现选中了整个页面,这种瞬间的错位感很难受。反过来看终端,不管是 less 还是 htop 还是 python REPL,Ctrl-C 永远是中断,q 永远是退出。这种一致性没有哪个框架专门设计过,是终端程序四十年来积累的惯例,我之前在终端程序的潜规则里详细写过。

TUI 为什么"自动胜出"

Fonseca 的结论是:原生 UI 工具链搞不定的事,TUI 捡起来了。

TUI 快、可以自动化、在不同操作系统上表现一致。你可以远程运行,不用折腾 X forwarding(在远程机器上显示图形界面的技术)。Claude 在命令行上取得了巨大成功,原因很简单:你专注于交互本身,不用操心底下的操作系统是什么。我可以从笔记本 SSH 到远程服务器上操作,体验和本地差不多。

对我来说,TUI 的优势不需要别人总结。Ctrl-C 退出、管道组合、远程无脑连,这些我已经用了十年。但读了 Fonseca 的文章才意识到一件事:我一直留在终端里,原因可能很简单,GUI 框架在过去三十年里把自己搞成了现在这个样子。

回头想想,也许不是 TUI 有多好,是 GUI 实在没给自己争气。

无主之地 TUI GUI 终端 Emacs