我觉得这篇文章关于 Emacs 界面交互的观点很深刻

以下是我用 Gemini 翻译成中文的文本:

The Emacs widget toolkit

在此博客文章中,我概述了几个月来反复考虑和深入研究 Emacs 显示代码的后果。

在本文中,我将概述 Emacs 窗口工具包的潜在发展方向,制定一个旨在复兴 Emacs 并使其达到一个新用户可以欣赏其作为杰作工程的程度的计划。

但首先,让我们谈谈问题。

“All that glitters is gold”

Emacs 并不丑。虽然有些过时,但这种旧风格反而增添了它一种复古的魅力。

大多数人认为,缺乏动画或其他花哨的功能是 Emacs 吸引人的主要原因,但事实并非如此。我们有相当酷的基于 SVG 的主题,而且 Emacs 具有长期的适用性。 Emacs 并非追求视觉效果,它不像一辆 Bugatti 跑车那样华丽,而更像一辆 Ferrari F50。它可能看起来有些丑陋,但你终将学会欣赏它的内在价值。

所以,如果 Emacs 的问题不在于视觉效果,那么使用 Widget 工具包还有意义吗?

GTK was a mistake

GTK 是一个关于如何不应该设计工具包的案例研究。它的唯一优点是它提供 C-ABI,这意味着您只需要对编程语言进行一些小调整,就能创建链接到系统 GTK 库的程序。这是 GTK 存在的唯一原因。它很便宜而且容易设置。

在 Trolltech 经常戏弄人们并威胁将其 Qt 改为专有软件的情况下,以及随之而来的断裂和基于 C++ 的工具包的断裂,曾经发生过。最初的想法是,GTK 将是 GNU 的原生工具包,一切都将基于 GTK。GNU 网络对象模型环境出现后,情况似乎有所改善。

不幸的是,Gnome 2 最终未能持续存在,以及理性的开发实践、相互的尊重的态度和生产力的日子被我们今天所看到的所取代。

最初名为 Gimp 工具包的 GTK 工具包,是问题的开端和终点。它是人们选择避免设计跨平台原生程序的原因的 alpha 和 omega,并专注于将 Chrome 塞进一个软件包中,以及一些似乎是代码中少数部分的网页。

这个工具包具有一种不寒而栗的能力,可以扔掉完美运行的代码、破坏向后兼容性,并且似乎旧程序在较新的工具包上运行得更糟,这/似乎/不是 GTK 的错。

它是一个动态链接库,几乎没有任何能力运行旧程序。在之前支持并证明在其他领域有价值的特性已经被剥夺了,比如复杂程序。开发团队似乎认为,就像苹果一样,他们能够生产简单程序,这些程序在背景中消失,并且不需要配置,并且他们的设计是唯一您可以看到的。GTK 对不配置的原则立场,与缺乏实际资源来真正地做到不配置的结果,导致 GTK 程序必须不断地追赶,并且不知道下次会删除什么。

那些为 GTK 的政策辩护的人似乎相信了标题党谎言,并且没有深入挖掘。该工具包并非最小化,因为它既没有减少攻击面,也没有提供一个小型且稳定的特征集,可以依靠。有主要版本以一种“吃或扔掉”的方式提供,像 Linux Mint 这样的有识之士选择了软件工程领域的中间手指。

Gnome 和 GTK 并不相同:就像左手袜子傀儡与右手袜子傀儡一样。同样的糟糕主意在两个项目中的都盛行。选择一个,就选择了另一个项目的设计“哲学”。有多个例子表明这种紧密耦合是一个好主意:苹果做得很好,微软也做得很好,而谷歌,尽管有它的缺点和不一致之处,至少会为您提供足够的喘息空间,让您可以遵循或忽略他们的指南。不像 Gnome 一样,也不像 Flathub 一样,以及由此导致的 GTK 程序,除非它们落入伪极简主义的垃圾箱中,否则它们会被视为次要的。

GTK was a mistake for Emacs

现今使用 GTK 似乎仍然是一个好主意。为了更好地理解情况,桌面 Linux 正在转向 Wayland,一种取代 X11 垄断并形成一个寡头市场的协议。这意味着一些以前的方式不再适用。对于终端 UI Emacs 没有任何变化,但对于其 GUI 程序本身,则需要进行调整。

与其一头扎进 Emacs 中,添加条件编译指令并试图解决无法解决的问题,不如利用 GTK,它不仅实现了,而且似乎主导了许多协议。太棒了!

然而,结果却完全不尽如人意。PGTK 版的 Emacs 提供的优势很少,甚至没有可察觉的优势。它仅提供略微改善的字体渲染(与 WebRender 和 Qt 相比仍然不佳),并且修复了剪贴板。这个列表还很长,

这个构建不标准,在X11上无法工作,并且无法禁用相关的错误提示;它更易于出现卡顿,因为UI线程每绘制一次调用会执行更多工作;它无法在KDE Plasma上调整大小,只能最大化和最小化;它有一个长期存在的 bug,会导致崩溃显示服务器时也会导致 Emacs 服务器崩溃;它会向终端输出大量的警告,这些警告既无法修复也不能被忽略;它的主题化能力很差,GTK主题很容易与Emacs的其他部分形成对比;这是一个不断变化的构建,因为它当前将Emacs链接到GTK 3,而不是GTK 4,而第五版本正在紧锣密鼓地开发中。

也许这是因为 Emacs 没有充分利用 GTK?我认为 GTK 的功能实在太少,不足以支持其使用。一个令人信服的理由是 Lucid 工具包看起来有些过时,考虑到 Emacs 的 Chrome 占据的视图比例微乎其微,这让我觉得有点好笑。

Emacs 感觉不像一个图形程序,很大程度上是因为 GTK 提供的功能有限。你仍然更倾向于使用 consultdired 打开文件,因为图形化的“打开文件”对话框似乎遵循一套不稳定的规则。工具栏也鲜少有经过良好设计的图标,并且很少响应对变化的正确操作。customize 界面使用文本形式模拟实际的控件,这主要是因为 GTK 无法提供 Elisp 所需的这种高级控制。试图将 minibuffer 整合到专门设计的 UI 元素中,结果总是出现行为不佳,用户最终又会回到不使用 posframe 工具的习惯。alert 包,旨在提供通知,比用 Elisp 编写几行代码封装 notify-send 更不可靠。键盘事件处理仍然采用自定义方式。没有任何 UI 能够充分利用 GTK 的子集,Emacs 倾向于使用 Vue 和/或 PyQt 用于其显示。Emacs 内置的终端模拟器默认不使用 VTerm,只有通过第三方包才能启用。添加分片视图的最佳方法是模拟它们在文本中。玩 Tetris 的最佳方法不是使用 GTK 的内置功能。

菜单项也未能充分利用GTK的优势。快捷方式的显示方式绕过了GTK的处理方式,导致例如“Ctrl+Shift+F”在Inkscape和“C-M-f”在Emacs之间存在明显的差异。菜单栏不可靠,无法通过全局菜单快捷键(例如在KDE Plasma中)进行控制,而该功能在macOS上似乎运行良好。

诸如平滑滚动和针对特定操作系统(例如)的图形应用程序选择颜色等功能也相对缺失。平滑滚动并不平滑,它只是允许您在文本的非整数部分之间移动,这既不美观,也不实用。 缺乏对替代输入方式的支持,例如触摸屏和游戏手柄。 根本没有任何支持!这引出一个真正的问题,Emacs 从使用 GTK 中获得了什么?

事实上,对于这个问题,答案数量正在减少,除非GTK和Emacs都做出重大改变,否则不太可能改善。如果你当初来此文章是为了了解为什么不能仅仅修复PGTK构建并继续前进,你现在会明白,这根本无法解决问题。一个类似于GTK的工具包根本无法满足Emacs的所有需求。而且,鉴于Elisp提供的深度定制和控制,我认为主流工具包也难以做到这一点。因此,没有Qt移植。

Yes, there are two paths you can go by…

在这一部分,我们将概述两种最有可能的途径,以使 Emacs 更加灵活,并使其更像一个具有 WYSIWYG 功能的图形化程序,而不是一个复杂的文本处理工具。

Why plaintext is king

由于纯文本是 Unix 编程和 Emacs 的主要原因在于其普遍性。标准字符集是 UTF-8(即 Unicode),它在任何地方都能被渲染。交互方式也相对标准化,包括按字符左右移动、理解行、以及向上遍历(Emacs 默认支持,但并非总是如此)、对换行符、制表符和空格的理解。在 monospace 字体下,这些特性共同创造了一个舒适、一致的环境。

任何在 Emacs 中操作纯文本的函数都可以将这些信息反馈给 dired 并进行批量重命名和编辑。如果一个事物有文本表示,就可以编辑该文本表示,然后转换回来,实现“一劳永逸”。

这使得 UTF-8 成为一种通用的数据表示语言。复制、粘贴、剪切、删除等操作,以及大多数键盘的“自插入”行为,允许使用一套可转移的技能直接与大多数数据交互。例如,如果要创建一个在 Emacs 中编辑视频标签的文件(Incidentally, this is on my to-do list),可以通过提供可预测的、普遍的导航,而无需过多思考。这些操作相互补充。学习如何使用 forward-sexp,也能在 FORTRAN、Algol、C、Rust、Elisp 和文件名等环境中进行。如果某个操作是上下文敏感的,则必须提供教程,尽管从严格意义上讲,最好的学习方式是通过观察——闪烁的光标、行/列布局的 monospace 字体,以及一些其他技巧,为每个人提供一个熟悉的地方。

图形界面没有这种类似的谓词集。如果我想按下特定的按钮,就有一种/某些可能性,图形工具包会提供我可以按键进行操作的按钮,但这些按钮似乎是任意的,只有当我按住 =Alt= 键时才会显现。这些快捷键可能很高效,但大多数时候,它们是基于阻塞操作,因此,如果要运行一个深藏在菜单中的快捷键,需要按住 =Alt= 键并输入一个很长的序列,很可能会错过想要按的按钮。而且,并非所有操作都表示为菜单项。在网络上,你只能希望程序的设计者给你提供足够的提示,为必需的对象赋予焦点能力,并且你不需要长时间按住 =Tab= 键,才能最终按下想要的按钮。这种控制力非常有限。

对于普通人来说,这种差异可能不明显,但对于 Emacs 用户来说,这些差异会累积起来,你就会开始怀念一个更简单的时间,那时一切都是文本缓冲区。但这并不意味着图形工具包本质上就无法提供这种统一的导航方式。毕竟,网格是普遍存在的,六边形坐标系统并不常见,而且如果文本不是 monospace 字体,你所去的地点和你所想去的地点并不总是对应的。

然而,很少有工具包提供足够的键盘和鼠标控制水平,因此你无法通过图形工具包完全复制 Emacs 的功能。更何况,要用控制器导航它们,你实际上是在模拟键盘。

那么,我们需要什么呢?

Uniform navigation verbs

关键原因之一是为什么 Emacs 如此出色,并且其影响力至今可见于 macOS 中,在于其丰富的导航动词。您有前进和后退的概念,也有单词、行、句子和 S-表达式之间的差异。在理论上(尽管并非在实践中),如果用户界面词汇标准,而且大多数情况下确实如此,那么您可以以类似的方式定义这些事物。

诸如 =avy= 之类的软件包允许您随机访问屏幕上的任何内容。它们是终极的导航工具,但并非人们直观使用的工具。这种词汇在 KDE 中仍然存在,例如,使用下划线标记特定事物,以表明可以按下 =Alt + <该键> = 来使用该对象与文本。这是一种有限的导航形式,因为符号交互对象数量是非零的。尽管焦点可以替代点,但在 Emacs 动词中,点可以同时指向多个事物。它可以指向一页、一个文件、一个标识符,或者 minibuffer 中的一个选择… Emacs 中的动词非常有限,因此如果我们想要推动进展并提供足够丰富的系统,我们需要创建等效的东西。

另一个约束是交互必须是自然的。而这正是 Emacs 过去 通过文本模拟许多图形元素发挥作用的原因。网格布局和行/列无处不在。还有组和容器。只需指定一个主要功能按钮(例如,= =)来使交互正常工作,这幸好我们已经有了。也许值得直接触发某些函数,并且必须有一种方法来指定给定时间点绑定哪些函数,但诚然,这些都相对容易地在 Emacs 中分类,这要归功于其 =一切皆函数= 的理念。

这些不仅用于专用模式。LSP 提供了多个交互元素叠加在文本缓冲区上。扩展这些信息,确保尽可能地使其可用,并将这种功能从 LSP 中分离出来,并将其引入主模式,这与 Emacs 的核心价值观相符。这意味着方便的 UI 元素可以引导您避免犯愚蠢的错误,并且在不使您的生活变得更加痛苦,尤其是在滥用绘制预算的情况下,也是一种理想的解决方案。

缓冲区在文本方面似乎效果很好,但缓冲区可以是多形的。这对于 Emacs 的图形 UI 直接工作需要进行必要的更改,但可以推迟。如果代码更改正确地进行,应该对用户透明,只需提高低级绘图 API 的效率,而不会影响高级。这是关键所在,我们不能破坏用户空间。尤其是考虑到 Emacs 的用户对变革持抵制态度。

SVG

这种方法,在某种程度上已经相当普及。你只需将 SVG 添加到缓冲区,并通过操纵对象来布局它们。

但这可能不是我所指的,但如果这种方法足够高效,它/可能/能行。简单地说,大部分的繁重工作,包括布局和渲染矢量图形,都是由我们完成的。这些布局和图形在各个平台上都是一致的,如果经过适当的组织,即使计算成本较高,也能发挥出奇妙的效果。所以,即使有点低效,与 HTML 相比仍然更快。

这种方法的缺点很明显。它仅限于 SVG 的能力。当然,我们可以嵌入大量的媒体,但这些媒体需要复杂的交互。否则,解决所有这些问题的简单方法就是创建一个 JPEG 的布局并显示它,而不是主窗口。

这在原则上不是一个坏主意,但更有可能成功,因为社区已经在朝着这个方向发展。例如,Nicholas Rougier 的出色工作,以及像 =nova= 这样的项目,允许你使用迷你缓冲区做许多有趣的事情(当它决定工作时)。通过将 SVG 嵌入到代码和文本中,可以提供丰富的命令集,从而可以做很多事情。虽然这些都不是理想的,但它们比没有好,并且朝着这个方向已经可以开始。

我的朋友 Divya Ranjan 已经有一个功能齐全的便携式 PDF 阅读器,它比其他任何解决方案都要好,并且依赖于 SVG。扩大在这一领域完成的工作量可能不是一个我们需要一概而论地否认的想法。

然而,也需要认识到这是许多人陷入的常见陷阱。使用浏览器窗口显示文本与使用 SVG 显示缓冲区内容之间的原则区别在于,HTML + JavaScript 在更长的时间内共同演化,而 Elisp + SVG 以及它们早期作为二者的结合,尽管这两个标准在实践上已经相当成熟。

另一个问题是效率方面的问题。SVG 的渲染是一个阻塞过程。Emacs 没有足够可靠的 =async= 运行时,无法让这些效率方面的毛刺逐渐退化到背景中。过度依赖 SVG 来处理一切都可能导致双重困境:SVG 可能会改变,Elisp 库也可能改变。

更根本地来说,这会阻止针对特定应用类型的某些优化。最自然的表达方式可能效率低下,因此像使用带有帽子的NPC作为交通工具这样笨拙的方法是可以预期的。这在个人项目上并非问题,但仅限于个人项目,就无法提供某些默认的质量提升软件包。我很乐意投入大量精力来设计一个 SVG 在 Emacs 中发挥更大作用的未来,如果我确定它不会像使用文本渲染UI元素的原始“黑客”方法一样,导致它几乎从未被使用。

A custom toolkit

目前看来,完全将 Emacs 与任何现有库隔离,并尝试独立发展,可能是一个不错的选择。这并非意味着它必须与文本编辑器耦合,而是 Emacs 也许可以成为下一个 Chrome,如果玩法得当,Electron 程序可能会被 Emacs 程序所取代。

要实现这一点,需要付出大量的努力。

需要彻底扩展 Emacs 的可编程性,充分理解 Emacs Lisp 的优势和劣势。 就像 JavaScript 受到压缩截止日期影响而做出决策一样,Emacs Lisp 同样基于对未来编程不准确的评估。 相比之下,Emacs Lisp 拥有“技术债务”的优势,即由于其历史悠久,大多数不一致之处可以归结为“技术债务”,而实际上修复这些问题既简单,而且如果没有少数“老古董”(讽刺的是)坚持使用默认设置,这些问题早就得到了解决。

Emacs 需要一个低级别的自定义工具包。它需要能够从 Elisp 中绘制,并且绘制得非常好。 我们需要一个与 SVG 类似的东西,虽然不是在语言上,但在目的、丰富度和结构方面。

虽然可能会让人觉得这是不可能的,但历史上已经有许多更雄心勃勃的项目被尝试、实施和发布。问题在于框架和缺乏规划。 有些项目做的事情类似,但没有明确的范围、没有对所需时间和完成日期有概念、也没有可量化的进度报告。 这个项目需要足够优秀,以至于您可以发起募捐活动,邀请来自不同背景的程序员全职捐助。 我是真的这么说的。 我有很多不太雄心勃勃的项目在积压中,我真的需要一个能推动进步的项目。

直接使用SDL以获得跨平台,但极其低级的API。将这些低级API暴露给Elisp,并允许使用Emacs的模块系统进行静态链接和交互。 建立一个基于Elisp的消息传递系统来控制UI。 扩展现有的键盘系统以与各种输入方法(例如Steam Deck控制器)一起使用。 创建一种基于Elisp的最小化QML风格布局定义语言,该语言使用极简的系统进行主题化。 我们不需要/也不需要完整的CSS,但继承面和覆盖层可能是有用的。

理论上,拥有一个低级API,可以将一个想法转化为一个Emacs包,并使其能够独立执行,并非不可能完成的任务。 理论上,Emacs仍然可以占据主导地位,如果能够快速创建一个用于常见任务的GUI。 在Elisp中,这已经很大程度上可行,但像C和C++这样的语言的减少功能和表达力,使得创建功能性的GUI变得困难。 Qt需要Moc才能做到,而GTK则必须模拟一种伪面向对象环境,才能让程序运行。 考虑到这些,我们处于更有利的位置。

There’s still time to change the road you’re on

我做了一些关于 Emacs 代码库的研究,并希望能分享我的发现。不过,内容可能会过于枯燥。这可以看作是 Emacs 控件工具包的宣言,旨在创造一些优秀的东西。

我计划进行更深入的探索,了解底层机制,并尝试通过低级别的编程魔术来插入我们的位置。

我也需要你们的反馈。

如果您正在阅读此文,欢迎向我提出匿名(或非匿名)建议,请发送邮件至:appetrosyan at linux full-stop com

请务必对以下主题发表您的看法:

  • 帮助作为 Elisp 程序员的愿望
  • 帮助作为 C 程序员的愿望,拥有 SDL 知识
  • 帮助进行筹款的愿望
  • 帮助撰写文档的愿望和能力
  • 关于 Elisp API 应该如何设计的想法

这希望是许多帖子中的第一篇。我真诚地希望能够尽快在我的个人作品集网站上建立评论区,以便您能提供更及时的反馈。总而言之,我希望这段旅程能将我们带到一个美好的地方。

Last Updated:: 27/04/2025, 01:13

Contributors: Aleksandr Petrosyan

2 个赞

作为用过各种桌面环境的Linux用户,感觉GTK默认的类似GNOME的Nautilus的文件选择器完全不是给人用的,关键是基于GTK的桌面环境都不能改这个默认的文件选择器。

最大的问题还是人力不足大家想要的功能又多。

几个有意思的 Emacs-like 编辑器:

1 个赞

我觉得,由于用户品味所导致的开发资源的不平衡。但现在应当要有人去强力扭转这个问题了。

一周前在Reddit上看到了相关的讨论,有个用户的评论 我觉得也挺有道理的,摘部分翻译一下中和一下文章里的负面意见吧:

评论里为 GTK 的辩解(Gemini 翻译)

在Linux系统中,图形用户界面(GUI)和桌面环境向来都像是二等公民。自由的Linux世 界只能从企业界获得一些残羹冷饭。当企业界从Unix桌面转向Windows/Mac桌面时,Linux 基本上就停留在了Unix桌面黄金时代的那个技术水平。

Linux桌面社区是一个分裂的社区,并且已经分裂了超过25年。从90年代开始,似乎每个 人,连同他们的七大姑八大姨,都在为类Unix(*nix)系统发明窗口系统和工具包,其中 大多数都受到了X11的启发。

X11饱受诟病,然而,X11在一些基础方面做得非常出色。它也是开源的,每个人都在学习 它,每个人都有自己的想法,都想做一些新的东西。当然,X11也有问题,每个系统都有 问题,但是大家并没有去修复X11,而是每个人都想成为开源和工具包领域的英雄,每个 人都在推行自己的议程。这就是开源的诅咒。大家不是团结协作,而是各有各的算盘,都 想推行自己的理念。结果就是现在这个样子。最终Wayland取得了一些进展,但每个人仍 然需要X11。工具包也不得不为不同的窗口系统维护多个后端等等。

GTK最初只是一个“普通的”X11工具包。后来他们将其移植到了Windows和Mac上,并意识到 需要对窗口系统和操作系统后端进行抽象。最终他们也进入了Web和云领域,意识到需要 进一步抽象,并进行了更多的重构。

这篇文章的作者显然不知道事情为什么会是现在这个样子,没有对历史进行研究,也不理 解要让一个窗口系统和一个工具包正常运行起来所需要的工作。我建议他去查阅一些关于 Java AWT和Swing的旧文章,研究每种方法的优缺点。

像Emacs这样的应用程序有两条路可走:要么走AWT的道路,使用底层平台(Gtk、Qt、 win32等)提供的任何东西;要么走Swing的道路,只使用基本的平台窗口系统(例如 X11/Wayland、win32),然后实现自己的控件和绘图。Emacs是一个非常特殊的应用程序, 它实际上只需要子框架来实现它所使用的那些控件(菜单、菜单栏和按钮),但这意味着 要自己实现它们,可以用Elisp也可以用C语言。这完全是可行的,并且可以跨平台,但对 于那些在乎外观的人来说,与原生系统相比可能会显得格格不入。

然后是文章内容的评论

GTK was a mistake for Emacs

选择 GTK 是 Emacs 犯的错

PGTK 主要是为了在 Wayland 上支持 Emacs。当然,不借助 GTK 实现 Wayland 支持也是 有可能的,只是那样的工作量会相当大,这也是开发者选择 PGTK(而不是重写)的原因。

The reason why Emacs doens’t feel like a graphical program has everything to do with the fact that GTK doesn’t offer much of anything.

Emacs 不像典型 GUI 程序的原因是 GTK 的不足

这与 GTK、PGTK 等等都无关,Emacs 本就不是为了 GUI 设计的。Emacs 更像是字符渲染 的那种 TUI 游戏,同时适用于无 GUI 环境和图像界面环境。

The customize interface uses textual facsimiles of actual widgets because GTK would simply not allow that level of control from Elisp that you would need.

Customize 界面使用文字效果来效仿 GUI 控件的原因是 GTK 不提供 ELisp 所 需的高度可控的 API。

Emacs 设置界面没有 GUI 化的原因只是因为没有人想去这么做。

译者个人理解:

  1. Emacs 同时支持 GUI 和 TUI
  2. Emacs 下一切均 buffer,包括 Customize 界面
  3. 我们希望 GUI 和 TUI 共用尽可能多的代码,同时不同 buffer 均共用文本渲染代码
  4. 结论:GUI 和 TUI 必然看起来差不多
  5. 除非:有人为了 GUI 而 GUI 去把 wid-edit.el 重写一遍,同时加上大量的 C 代码 提供 (1) 一套对应的渲染代码,(2) 一套仅 GUI 下使用的 ELisp API

下面是个人意见:

  1. 对于 Emacs Customize 这种“文本效仿GUI”的控件界面,我与作者的意见相左。作者认 为这是一种 hack,但……首先从历史上来说,Emacs 诞生的时候还没GUI吧?而加上GUI支 持的时候和TUI保持一致外观也是非常自然的,何来hack 一说?

    当然,让按钮/文本框/各种控件看起来更“GUI”一些这个想法本身似乎没啥问题。但 Emacs 里的文本控件的优势是能够像普通文本一样选中/复制/查找,这是目前我所知的 所有GUI框架(除 contenteditable 外)都做不到的,除非像作者一样打算从头写起。而这也印证了上面所说的:这不是 GTK 的问题。

  2. 用 SDL 提供跨平台功能:

    ……我希望所有打算从头/半从头实现文本渲染的人都能去读读下面几篇文章:

    如果 GTK 不能满足 Emacs 的需求,那么 SDL 作为一个主要用于游戏的库就绝对没法满 足 Emacs 的文本编辑需求,除非继续“从头写起”或是直接放弃BIDI支持。

  3. 再为 GTK 说几句:之前我也在查Rust下的GUI框架,结果发现了 A 2025 Survey of Rust GUI Libraries 这篇文章。总结起来就是大多框架都不太行,唯一一个支持屏幕阅读器和输入法的还是基于Qt 的。 GTK也不支持Windows 下的屏幕阅读器,但至少这几个月的 GTK 4.18 似乎会更新支持(而Linux下则是早就支持了)。

    在 Unicode 更新了好几版的2025年,我的确觉得下面这些要求也不算严苛了:

    • Font fallback,在遇到默认字体不支持的字符时自动根据系统配置查找支持的字体
    • Bidirectional text (BIDI),中英文从左到右排,阿拉伯语从右到左,支持两种的混排
    • 系统输入法,包括输入以及候选框跟随光标等
    • 屏幕阅读器以及其它无障碍访问功能
    • 跨平台(上面所有提到的)

    但,奈何就是有很多拉丁语系开发者认为字符只有英文和emoji,然后把上面的坑一个一 个踩过来。在这里面,GTK(或是其它有足够历史的框架)虽然有很多历史遗留和各种问 题,但上面几点的支持都还算是做得不错的了。

但 xkcd 真是永不过时: xkcd 927: Standards

2 个赞

关于这篇文章,我其实对它提出的具体实施方向是不感兴趣的,但我觉得它指出的问题,实际上不是 Emacs 是否使用了 GTK,这篇文章真正讨论的,是 Emacs 在 Package 方面缺乏一个较为统一的 UI&UX 标准、框架。

如果用网页前端开发类比,Emacs 有浏览器,有 JavaScript,但没有 CSS。这导致各类行为(窗口弹出、分割、调整),还有不同 Package 在界面和交互方面的表现力,需要开发者自己写大量的代码,来调整界面。这是我开发 org-supertag 强烈体会到的,为了能够平滑 org-mode 原有的一些交互、使用体验,很多组件的代码中,至少有一半是留给绘制 UI 和交互的。

如果说,Emacs 原本是从 TUI 发展而来的,那么如何看待 neovim 在 TUI 所达到交互一致性和体验的流畅度呢?

我已经觉得过多的强调 Emacs 本身的技术发展历史,也属于「技术债」之一。

囿于我自己的背景、和能力,我其实对 GTK、PGTK 等图形协议缺乏深入的了解。所以,以上回复只能代表我的个人偏见,我不觉得我的想法一定正确。但从实际开发来说,我真的觉得 Emacs 很缺一个类似 CSS 的框架(即便是简陋的),其实 Emacs Widget 应该属于这类框架和协议,但它本身不成体系(我这方面有发言权,因为我用 Emacs Widget 开发了 org-supertag-query 的界面)…

4 个赞

不得不说Emacs的魅力也在于此,如果没有Emacs对代码执行的自由,我将被困在繁重的框架适应体系中,从而与编程分道扬镳。昨天去尝试了LazyVim并试图配置了其LSP & Linter,虽然最后以各种方式成功了,但我完全无法搞懂这些层层嵌套的设置标准下到底哪些代码是如何执行的。底层=简单有时也是一种反直觉的现象

有一个框架可以让大部分人降低开发成本,这是实际的意义。采用或不采用框架,本身是开发者自己的决定。但作为基础框架,应当提供的,太缺乏了。我不喜欢 LazyVim 的样式(过于花里胡哨,将过多资源渲染在动画上),但交互行为较为统一,这实际上是好事来着。

(btw碎碎念:统一也不是什么好事,且不说被降低开发成本的大多是既得利益者(已经擅长扩展配置的),common lisp开发环境就肉眼可见地无法融入进lazyvim,无论slimv还是vlime。多数人建立越复杂的标准,少数人就更容易被逼到角落,common-lisp这样不可能静态分析&没有LSP的语言是这样,性少数是这样,精神疾患是这样,或许前苏联人也是这样。我不好说)

1 个赞

从工具的掌握来说,肯定是熟练者为先的。就 Emacs 的上手难度来说,基本上能够开发 Package 的基本上配置也比较熟练(至少对 Emacs 的组件和工作机制有一定的了解)。

不理解,这里说的既得利益者是指什么?Emacser 里能有什么既得利益者?

建立标准,不意味着复杂。简单的框架,有法可依,就行了。就像约法三章,即便是 3 条系统性的规范,只要足够用就行。

1 个赞

其实 lazyvim 框架不算复杂的。你去翻他的源代码,整体挺精简的,没有什么过度的包装。

doomemacs 和 lazyvim 我都有用过,也看过他们代码抄了他们很多的配置。doomemacs 其实要比 lazyvim 要复杂很多。

要比还是得框架对比框架,才算比较公平。

话说回来,论配置窗口的显示规则,其实 emacs 提供了标准的用户配置窗口的显示接口 display-buffer-alist,绝大多数的包都尊重这个变量。

这个反而是 neovim 并没有类似的东西,配置窗口显示规则基本上都是每个插件都是自己提供自己的标准。

1 个赞

嗯嗯,后来退而求其次换doom了。lazyvim确实很圈粉,可惜对Common Lisp的支持太糟糕了,或许我有机会去学学lua自己搞一搞,哪怕给vlime做一个好的layer呢

这个是因为 lazyvim 的作者做了很多的工作,尽可能的把所有插件的打开窗口的方式都自己配置,尽可能调成统一,并不是因为 neovim 天生提供了类似的接口。

其实配置窗口的显示规则,其实 emacs 提供了标准的用户配置窗口的显示接口 display-buffer-alist,绝大多数的包都尊重这个变量。

这个反而是 neovim 并没有类似的东西,配置窗口显示规则基本上都是每个插件都是自己提供自己的接口。

我误以为 LazyVim 的统一交互,是由于 neovim 提供的。这里更正我的例子,实际上我是指 LazyVim。

这里不光是 buffer 的位置,还有包括 buffer 内的交互行为,LazyVim 是比较统一的,让人在使用的时候会有稳定的预期。

这和技术自由无关,只是人性如此。

实际上,我一直在做 emacs tui 框架(ETAF: emacs text-based application framework )的工作,可以实现 组件化,复杂布局,支持样式系统 和 事件交互,数据驱动,响应式更新,后端数据库绑定等等。

工作量庞大,拿起又放下,从最初的想法开始搞,断断续续有几年了 :joy:,(被各种困难卡住,觉得搞不懂,哪天又来了 兴趣,换一种设计接着搞,基本是这种状态) 。这两天组件化有了一些进展

响应式和组件化借鉴了vue,布局系统借鉴了 bootstrap的,也研究过 grid布局,样式系统准备参考 tailwind-css,数据库搞了一个orm封装现成的sqlite函数,页面节点的更新准备借鉴ewoc,但是要搞一个tree版本的,而不是双链表,因为复杂布局本质上是一个树…. 事件绑定可以预见就是各种自定义的hook来实现。

但是可以预见,最终的效果肯定不会像gui那么的灵活和完美,因为在 elisp层面去做有很多效果从emacs底层就不支持。但也够用了,因为emacs主要还是用于文本编辑,tui框架主要适合做各种需要前端展示和交互的应用程序(类似 telega 等)。

我经常容易陷入到技术或设计的细节里面,总想搞出一个完美的,导致手上有很多半成品的工作,etaf就是最大的一个坑,最近计划把思路理一理,写个文档发出来,欢迎大家到时候一起讨论!

8 个赞

有链接吗?观摩学习下

暂时还没有 最近比较忙 后续整理好了发出来

从操作效率来说,纯文本界面并不会比GUI差,有时候不想动鼠标,就键盘操作了, 纯文本界面明显与全键盘操作更配。但有时候是触屏操作又不想用键盘,这时应该GUI更好。 我猜emacs GUI应该从未有过对触摸屏操作的优化

1 个赞

对比emacs的历史,移动手机的出现也还没有多少年,emacs android 出来也还没有多久 :joy:

她的意思是 lAZYvIM 的现有用户群都早已熟悉脱离框架进行最原始的配置, 但他们出于便捷性的考虑, 推广了框架性的配置方案.

而新入门者则因为框架的流行, 很难再找到手工代码配置的教程, 被迫裹挟去学习毫无迁移性的框架.