用SDL3重新实现Emacs 的图形窗口系统

这个干成了可不得了啊,将是Emacs一个跨时代成果。难度很大很大呀

1 个赞

不然,他怎么这么酸爽呢…

linux其实是需要一个新toolkit的,现在的情况是lucid没法正确处理鼠标事件,gtk3远古多显示器bug一直没修,而且pgtk和gtk3只能二选一

我来更新作者亚历山大的最新想法,大意是,为了抛弃原本历史包袱沉重的架构,他打算硬分叉一个 Emacs 的版本。而这个分叉当中,最重要的是对 Emacs 的结构进行重构。以下是原文:

An Update on the Emacs Widget Project

November 1, 2025 16-minute read 16 分钟阅读

This is a long awaited update on my misadventures with the Emacs Widget system. This update contains some good news. From some points of view, it contains all good news. But the tone is coloured by a few real world happenings, so it is not all positive. I will allow myself some profanity, more so than usual, and this may not be charitable.

这是我对 Emacs Widget 系统冒险经历的长久等待的更新。这次更新包含一些好消息。从某些角度来看,它包含所有的好消息。但基调被一些现实发生的事情所影响,所以它并非全是积极的。我将允许自己使用一些脏话,比平时更多,这可能并不仁慈。

Emacs, the Program

Emacs,这个程序

Emacs is a beast that you can love or hate. Having worked with it and using its packages for a very long time, almost a decade by now, I can say that it is my favourite programming environment. It is rather a good program, and it has a rich and fruitful history. It is a program that existed longer than I have. It is a program that can keep up with the modern day best-of-the-best programming environments.

Emacs 是一个你可以爱或恨的野兽。经过很长时间使用它及其包,几乎已有近十年,我可以说它是我的最爱编程环境。它是一个相当不错的程序,拥有丰富而富有成果的历史。它是一个存在时间比我长的程序。它是一个能跟上当今顶尖编程环境的程序。

And yet, the quality of the code base and the code repository is not what I would consider good. The fact that this program can run for as long as it does without causing any major issue with respect to memory, is a miracle. I can appreciate its design and capabilities, the same way I would appreciate the design and capabilities of the Great Wall of China. It is functional, purposeful, and the ugliest code base that I have worked on.

然而,代码库和代码仓库的质量并不是我所认为的好。这个程序能够运行这么长时间而不引起任何主要的内存问题,这真是个奇迹。我可以欣赏它的设计和功能,就像我欣赏中国的长城的设计和功能一样。它是实用的,有目的的,也是我所工作过的最丑陋的代码库。

When I started out, I had assumed that the causes of the issues with Emacs were deeply rooted, complex, and intricate. What I found is banal neglect. A text editor like this should cope with longer lines. A text editor like this ought to be able to interact with language servers and send a great deal more data. A software platform, such as Emacs, based around Emacs lisp can well scale to the level of an operating system, and cope with a great deal more performance-critical work. Do it well. The fact that it does not, has more to do with the fact that the blunt-force approach of accretion of features, without any design, any foresight or for that matter, any restraint, than it does with complex fundamental limitations.

刚开始时,我以为 Emacs 出现问题的原因是根深蒂固、复杂且错综复杂的。但发现的问题其实很平庸,是疏忽所致。像这样的文本编辑器应该能处理更长的行。这样的文本编辑器理应能与语言服务器交互,并能传输大量数据。像 Emacs 这样的基于 Emacs Lisp 的软件平台,完全可以扩展到操作系统级别,并能处理更多性能关键的工作。做好它。它之所以没能做好,更多是因为无设计、无远见、无节制地堆砌功能这种蛮力方法,而非复杂的根本性限制。

Elisp is not the enemy. The programming model is.

Emacs Lisp 不是敌人。编程模型才是。

What I Managed

我所完成的工作

I had been continuously experimenting with the code base, and I found that I cannot do many of the things that I wanted. Not because they are technically impossible, but because it requires a grand redesign of the program.

我一直不断实验代码库,发现我无法实现许多我想做的事情。不是因为技术上不可能,而是因为需要对该程序进行大规模的重新设计。

I managed to get very basic and unstable rendering of one buffer on screen using SDL. The performance was comparable to that of lucid. In all fairness, lucid is as fast as I can make the SDL backend, and is just as independent of the dynamic libraries on the system. Rewriting the backend to SDL accomplishes some things, but it would take years to replicate all of the existing functionality at the rate at which I managed to do it so far.

我使用 SDL 成功实现了在屏幕上渲染一个缓冲区的非常基础且不稳定的版本。性能与 lucid 相当。说句公道话, lucid 是我能做出的最快的 SDL 后端,并且与系统上的动态库的依赖性同样低。重写后端到 SDL 完成了一些事情,但以我目前实现的速度,要复制所有现有功能将需要数年。

The build system is the most consistent source of frustration. The code base has a plethora of platforms that it must support and in very specific ways, and just getting the program to compile on Linux and on Mac OS, required a considerable amount of duplicated effort. While the low overall quality of the code meant that most code generated by LLMs was an improvement, the tight coupling and contexts and layers upon layers of ad-hoc solutions resulted in what I consider untenable issues. If I myself struggle with the build system, and all I can offer is a poor proxy for what already exists in lucid what reason do other people have to engage with the code?

构建系统是最大的挫败来源。代码库必须支持众多平台,并且以非常具体的方式支持,仅仅让程序在 Linux 和 Mac OS 上编译就需要大量的重复工作。虽然代码整体质量较低,意味着由 LLMs 生成的代码大多数有所改进,但紧密耦合、上下文以及层层叠叠的临时解决方案导致了在我看来不可持续的问题。如果我自己都难以应对构建系统,而我所能提供的只是对 lucid 中已存在内容的拙劣替代品,那么其他人还有什么理由去接触这段代码呢?

The expansion of what the editor toolkit should be able to do requires some concepts to be restructured. Windows don’t work the way I need them to. They have way too many bits of data carried from multiple layers of abstraction to one mess of functions. It is not at all capable of what I want it to be. The limitations of posframe now become readily apparent, and explain why such functionality is often avoided. It’s not because such functionality is inherently difficult to implement… just that it would be inherently difficult to implement, without simultaneously rewriting much of the window.h and window.c.

扩展编辑器工具包应该能实现的功能需要重新构建一些概念。窗口无法按我需要的方式工作。它们承载了来自多层抽象的大量数据,最终变成一堆混乱的函数。它完全无法实现我想要的功能。 posframe 的局限性现在变得显而易见,这也解释了为什么人们常常避免这种功能。这并不是因为这种功能本质上难以实现……只是因为它本质上难以实现,除非同时重写大部分的 window.hwindow.c

Quite frankly what I need is something that is too close to window, to be accepted. People will say that because 90% of the functionality is shared, that I should use Windows for the purpose, and I should not implement viewports. In fact, not only would that extend to the people reviewing the eventual code merge into upstream Emacs, but also people in the audience today have suggested that. Extending windows with that 10% of extra functionality is intractable, and will open the door to many bugs. For this to be easy to do, one would have to do decades worth of refactoring.

坦白说,我所需要的东西与 window 太接近,以至于难以被接受。人们会说,因为 90%的功能是共享的,我应该使用窗口来实现这个目的,而不应该实现视口。实际上,这不仅会延伸到最终代码合并到上游 Emacs 的人,而且今天在场的观众也提出了这个建议。用那 10%的额外功能扩展窗口是无法解决的,而且会打开许多错误的大门。要使这件事变得容易,就必须进行几十年的重构。

Warning 警告

And refactoring is the death knell for the project.

而重构是项目的死亡之吻。

The reason why refactoring the code base, good though it would be an idea in principle, and necessary in practice, is not going to work has a very simple explanation. People are stupid.

重构代码库的原因,尽管在原则上是个好主意,在实践中也是必要的,但为什么行不通有一个非常简单的解释。人们很愚蠢。

The code is there in the project in the shape that it is. The code hasn’t changed, because most of the people working on it either have a pathologically poor taste and complete lack of awareness of why things are not usually done this way, or because they recognise it as problematic, but have learned to work around those limitations. In the former case the merge would be rejected, because of the implication that bad code is bad. People get defensive about their work. In the latter case, the merge would be rejected, on the basis upon which every initial change had been rejected: the activation energy needed to fix the original problem is too great. 代码以当前的形式存在于项目中。代码没有改变,因为大多数参与工作的人要么病态地缺乏品味,完全不了解为什么通常不这样做,要么他们认识到这是一个问题,但已经学会了如何规避这些限制。在前一种情况下,合并会被拒绝,因为这意味着糟糕的代码就是糟糕的。人们会为自己的工作辩护。在后一种情况下,合并会被拒绝,基于最初拒绝所有变更的理由:修复原始问题所需的活化能太大。

Getting this project into a merge-able state is a problem not just for me, because shall we say… I can foot the bill. It is a problem for the project maintainer. There’s volunteers that review the merge requests. There’s coriphei that produce horrible code in one place, but are kept around because their poor code solves a problem that a naive rewrite cannot (c.f. redisplay).

将这个项目置于可合并的状态是一个问题,不仅对我而言,因为……我们可以说,我能承担费用。这对项目维护者来说也是一个问题。有志愿者在审查合并请求。有 coriphei 在一个地方编写糟糕的代码,但他们被保留下来,因为他们的差劲代码解决了一个简单重写无法解决的问题(参见 redisplay )。

And I would not be able to do what I want. This is a list which includes:

而且我无法做自己想做的事情。这个列表包括:

  1. Floating toolbars and panels that can be docked as in professional applications.

可停靠的浮动工具栏和面板,如同专业应用程序中的功能。

  1. Nuanced input processing that allows for input of more than the keyboard, and is not confined to technical limitations that are at least two decades obsolete.

细致的输入处理,支持键盘以外的输入方式,不受限于至少已有二十余年过时的技术限制。

  1. Viewport system that would allow you to run Doom as an elisp sub-program inside of Emacs.

视图系统,允许你在 Emacs 内以 elisp 子程序的形式运行 Doom。

  1. High performance canvas, allowing one to use Emacs as more than just a text editor with overlays.

高性能画布,使 Emacs 不仅仅是一个带有覆盖层的文本编辑器。

  1. A flexible, portable and unencumbered programming platform for Elisp, that allows you to run Emacs as an operating system for distributing graphical programs, but with a unified system of configuration and packaging.

一个灵活、便携且无负担的 Elisp 编程平台,它允许你将 Emacs 作为操作系统来分发图形程序,但拥有统一的配置和打包系统。

  1. A high flexibility graphical toolkit that would allow you at least the same level of programmability as the web does.

一个高度灵活的图形工具包,它将至少让你拥有与网页同等级别的可编程性。

  1. All of this in the same Emacs package. It isn’t a separate plugin that you have to fiddle around with. It’s stock emacs.

所有这些都在同一个 Emacs 包中。这不是一个你需要费心折腾的独立插件。它是标准的 Emacs。

  1. Something which respects the ethical commitments of the project. It has a hard-line stance on freedom-restricting software.

一些尊重项目道德承诺的东西。它在限制自由软件上持强硬立场。

This is not another EAF. That already exists, and is far too unpalatable for me. This is not another posframe, because it is meant to be built-in.

这不是另一个 EAF。它已经存在了,而且对我来说实在太过难以接受。这也不是另一个 posframe ,因为它被设计为内置的。

And unfortunately this cannot exist. I would be butting heads with people that I should be friends with; I would be working around code limitations that I neither understand nor support; I would be committing to supporting a great many workflows, for which the old method of doing things works just as well.

但不幸的是,这无法存在。我将与本应成为朋友的人发生冲突;我将围绕我不理解也不支持的代码限制工作;我将承诺支持许多工作流程,而旧的方法同样有效。

I am in the precarious position of giving up on point 7.

我处于一个尴尬的境地,不得不放弃第 7 点。

Note 注意

I must fork, and start from basically a minimal Elisp environment. I must build to Emacs, what neovim was to vim.

我必须分支,并从基本上一个最小的 Elisp 环境开始。我必须构建 Emacs,就像 neovimvim. 一样。

I can only hope that this code will eventually be the way by which mainline Emacs operates, but for that to happen it must do some things right.

我只能希望这段代码最终会成为主线 Emacs 运行的方式,但为了实现这一点,它必须做一些正确的事情。

Why Fork

为何分支

The simplest answer, is because it allows me to keep the things that I like about Emacs, and get rid of things that I dislike. And there are forks of Emacs, there was the Guile port. There’s the rather misguided emacs-ng and before that there was remacs. There are a dozen of half-finished Emacs-based half-projects that have become abandoned, because the code was too radical to be merged upstream. Some of these included great ideas, such as more efficient communication with Elisp.

最简单的答案是因为这让我能保留 Emacs 中我喜欢的东西,并去除我不喜欢的东西。而且 Emacs 有分支版本,有 Guile 版本。有相当不成熟的 emacs-ng 版本,在那之前还有 remacs 版本。有十几个基于 Emacs 但未完成的半项目版本已经废弃,因为代码过于激进无法合并到主线。其中一些包含了很好的想法,比如更高效的与 Elisp 通信。

I shall therefore explain why I want to do something that is a bit more radical.

因此,我将解释为什么我想做一件稍微激进的事情。

Decoupled Code 解耦代码

The main issue with the way in which Emacs operates is that it is a monolith. It being a monolithic repository is bad enough, but many of its components cannot be modularised. I cannot extract the graphical toolkit into its own library and expose an interface that can choose the toolkit live. It must be a monolith.

Emacs 运作方式的主要问题在于它是单体应用。作为一个单体代码库已经足够糟糕,但它的许多组件无法模块化。我无法将图形工具包提取为独立库,并暴露一个可以实时选择工具包的接口。它必须是单体应用。

remacs and emacs-ng have done precious little to fix this. If anything, they made the situation worse, because instead of having reusable and re-used components, they instead provided a single executable that bundled everything.

remacsemacs-ng 几乎没做什么来解决这个问题。实际上,它们使情况变得更糟,因为它们提供的是一个捆绑了所有内容的单个可执行文件,而不是可重用和被重用的组件。

What I would like to have instead is a clear separation of concerns.

我想要的是明确的责任分离。

ELI

I want there to be eli which stands for Emacs Lisp Interpreter. It is a stripped down version of the core of Emacs. This is equivalent to python3 on the command line, and it has the option of loading select packages and scripts. This allows Emacs Lisp to be used as a scripting language.

我希望有一个 eli ,代表 Emacs Lisp 解释器。它是 Emacs 核心的精简版本。这相当于命令行上的 python3 ,可以选择加载特定的包和脚本。这使得 Emacs Lisp 可以用作脚本语言。

Gel, Gef, Gdired

I want there to be gel and gef. The former is a library of reusable components that can be called from Elisp, and that allow you to create User Interfaces. This is the toolkit. The Graphical Emacs Library should be something on feature parity with TkInter, and used as the basis for most of the editor. The graphical Editor Frame is the entrypoint into the text editor component. It leverages gel to draw the editor window. It is the text editor component, but it is not all of the system. It leverages Elisp, and it can run some of the plugins that regular Emacs can, but it is not limited to that.

我想要有 gelgef 。前者是一个可以从 Elisp 调用的可重用组件库,它允许你创建用户界面。这就是工具包。图形 Emacs 库应该与 TkInter 具有相同的功能特性,并作为编辑器的大部分基础。图形编辑器框架是进入文本编辑组件的入口点。它利用 gel 来绘制编辑器窗口。它是文本编辑组件,但它不是整个系统。它利用 Elisp,并且它可以运行普通 Emacs 的一些插件,但它不限于这些。

I would then like to add more components to the system. I would prefer that there be more than just a few. Dired is a file manager that works around the limitations of the text editing paradigm. Textual interfaces allow great many things. But they are also limited and limiting. I believe that a file manager that leverages some of the graphical components, should exist.

然后我想在系统中添加更多组件。我希望不止只有几个。Dired 是一个文件管理器,它围绕着文本编辑范式的局限性工作。文本界面允许做很多事情。但它们也有局限性和限制性。我相信应该存在一个利用一些图形组件的文件管理器。

Magit

Ideally the way in which the system is designed would permit packages such as magit to work with minimal porting. I want there to be interoperability between Emacs, and the components that I will design.

理想情况下,系统的设计方式应该允许像 magit 这样的包在最小的移植工作下运行。我希望 Emacs 和我将要设计的组件之间有互操作性。

Use cases 用例

Imagine that you are dealing with an exotic deployment system. It’s kinda like Docker, but weird. You can write a few Elisp files to wrap the program in a UI. We are doing this today with Emacs already, I’m just thinking of providing those components a different way.

想象一下,你正在处理一个异国情调的部署系统。它有点像 Docker,但很奇怪。你可以写几个 Elisp 文件来将程序包装在 UI 中。我们已经在 Emacs 中这样做了,我只是想以不同的方式提供这些组件。

Those components show up in your graphical window manager’s task-bar with different icons, can be tiled with your system’s built-in windowing program, and are effectively indistinguishable from what you could create with PyQt. Except it’s not Python.

这些组件会在你的图形窗口管理器的任务栏中以不同的图标显示,可以用系统自带的窗口管理程序进行平铺,并且与使用 PyQt 创建的内容几乎无法区分。只是它不是用 Python 编写的。

Then you have a collection of CLI programs that create those windows. One of which is a shortcut to a macro-based editor. You use it they way you would use sed, except instead of trying to do the manipulation in your head, you open your gef, record a macro, as you would, close the frame, and it automatically inserts the directives. They can be in-line, and they can be a file. Sort of unix-y, except convenient and easy to reason about.

然后你还有一系列创建这些窗口的命令行程序。其中一个是基于宏的编辑器的快捷方式。你使用它的方式与使用 sed 相同,只是你不需要在脑海中尝试进行操作,而是打开 gef ,记录一个宏,就像你平时会做的那样,关闭框架,它会自动插入指令。它们可以是内联的,也可以是文件。有点像 Unix 风格,但方便且易于理解。

Then there’s going to be eplot, which is a scientific plotting program that has a native Elisp-based drawing system that gives you access to calc. But it draws to PDF, to ePS, to the screen and runs fast.

然后还有 eplot ,它是一个科学绘图程序,具有基于 Elisp 的原生绘图系统,可以让你访问 calc 。但它可以绘制到 PDF、ePS、屏幕上,并且运行速度快。

Finally, your gef can multitask and multiplex. The best way to put it, is to say that the current Emacs doesn’t need multithreading as much as it needs the equivalent of Posix processes that d on’t necessarily load all of your customisations.

最后,你的 gef 可以进行多任务处理和多路复用。最恰当的说法是,当前的 Emacs 不需要多线程,而是需要类似 Posix 进程的等效功能,这些进程不一定加载你所有的自定义设置。

Multiprocessing 多进程

The current greatest headache is the amount of time, a task could have been done easily in the background, but is instead done in the foreground thread, and locking up the UI.

目前最大的难题是时间,一个任务本可以在后台轻松完成,但却在前景线程中执行,导致 UI 被锁定。

This is not an inherent property of programmable editors. It is not necessarily a property of Elisp. It is, however, a property of how the programming model for Emacs looks like.

这不是可编程编辑器的固有属性。它不一定是 Elisp 的特性。然而,这是 Emacs 编程模型所呈现的特性。

Right now, all of your packages interact with potentially all of your packages. Every single line of Elisp can potentially affect every other line of Elisp. There is the concept of a buffer local variable, and lexical scoping is often encouraged, but not enforced, but because you cannot trust the script to do the right thing, you have to load one big interpreter instance, load everything into it, and block every time the GC runs.

目前,你的所有包都可能与你的所有包交互。每一行 Elisp 代码都可能影响其他所有 Elisp 代码。存在缓冲区局部变量的概念,通常鼓励使用词法作用域,但并非强制执行,但由于你无法信任脚本做正确的事,你必须加载一个大的解释器实例,将所有内容加载进去,并在每次 GC 运行时阻塞。

This cannot be fixed without a major rewrite. A major rewrite that can happen as a consequence of writing everything from scratch and imposing some further limitations onto Elisp.

这个问题不通过重大重构是无法解决的。这种重大重构可以通过从头开始编写并给 Elisp 施加一些额外限制来实现。

This means that the language can be updated such that packages can be loaded in two modes. One which is suitable for the new process-isolated model, and one which has the same behaviour in the old system. It may look like a collection of functions, setn that resolves to sending an inter-process message on gef, and setq in regular Emacs.

这意味着语言可以更新,使得包可以在两种模式下加载。一种适用于新的进程隔离模型,另一种在旧系统中有相同的行为。它看起来像是一个函数集合, setngef 上解析为发送进程间消息,而在 setq 的常规 Emacs 中。

This can and will eventually allow for more performance-oriented programming. Elisp is not a great medium for performance critical work, but neither was JavaScript back in the early days of the internet. Frankly, removing blocking calls and a universal stop-the-world style of GC will most likely fix most of the performance issues. Web-browser-based editors such as VSCode and Cursor don’t have particularly good performance characteristics either.

这最终将允许进行更注重性能的编程。Elisp 并不是进行性能关键工作的理想媒介,但早期的互联网时代 JavaScript 也不是。坦白说,移除阻塞调用和通用的停止世界风格的 GC 很可能会解决大部分性能问题。基于浏览器的编辑器如 VSCode 和 Cursor 的性能特点也并不突出。

Comprehensive Extensible Input

全面可扩展输入

The Emacs input system is rather archaic. The limitations that it imposes are both annoying and limiting. But imagine a different world. Imagine that you could have a macro pad that is entirely managed by the editor. Depending on the buffer, the major mode and some minor mode variables, the input of each key becomes context-sensitive. You can draw cartoons, such that even if you have no labels on the macropad, you could still figure out which key does what in which context.

Emacs 的输入系统相当古老。它所施加的限制既令人烦恼又具有局限性。但想象一个不同的世界。想象你可以有一个完全由编辑器管理的宏键区。根据缓冲区、主要模式和某些次要模式变量的不同,每个按键的输入都变得上下文敏感。你可以绘制卡通,即使宏键区没有标签,你仍然能够推断出在什么上下文中哪个键起什么作用。

Another example would be using the editor with voice commands. I quite happily use numen for most of my text input needs, but I’d rather be able to give context-sensitive commands through a programming model in a language that is designed to map input to action.

另一个例子是使用语音命令操作编辑器。我非常乐意使用 numen 来满足大部分文本输入需求,但我更希望能够在一种设计用来将输入映射到动作的语言中,通过编程模型给出上下文敏感的命令。

Elisp can do that very well with keymaps, but it struggles with other kinds of input. Mice and context menus are a great example of how some of this can be mapped back into keymaps as a concept, but I believe that a refactoring of the input system is in order.

Elisp 可以通过键映射很好地完成这件事,但它在其他类型的输入上表现不佳。鼠标和上下文菜单是这种概念可以映射回键映射的一个很好的例子,但我认为输入系统需要重构。

This will break compatibility with the input-sensitive packages in Emacs. But I quite frankly think that chorded input can only be done at the level of input event processing. The major modes provide syntax-table level context, but not other kinds of context. I believe that can be changed, but not in mainline emacs. Changing how major modes work, would break far too many packages, and in a fork, I can simply say “they are not compatible, use this instead”. Upstream, the collective voices of all the authors of the packages that I have broken will prevent the merge.

这将破坏 Emacs 中输入敏感包的兼容性。但我坦白认为,和弦输入只能在输入事件处理层面完成。主要模式提供语法表级别的上下文,但不是其他类型的上下文。我相信这可以改变,但不是在主线 Emacs 中。改变主要模式的工作方式会破坏太多包,在一个分支中,我只需说“它们不兼容,请使用这个替代品”。在主线中,所有我破坏的包的作者的集体声音将阻止合并。

Quite honestly, I’d rather not engage with that.

老实说,我宁愿不处理这个。

Comprehensive Accessibility

全面的可访问性

Emacspeak is an afterthought. I don’t have the best eyesight in the world. I may need to use it one day.

Emacspeak 只是一个临时想法。我的视力并不好,也许有一天我会需要用它。

I’d rather have something that is a much more robust system.

我宁愿拥有一个更健壮的系统。

Elisp Programs Elisp 程序

I sometimes need to use Magit just to manage the Git repository. At the moment, running that is a matter of:

有时候我只需要用 Magit 来管理 Git 仓库。目前运行这个只需要:

  1. Open editor window. 打开编辑器窗口。
  2. Navigate to the location 前往该位置
  3. Open Magit. 打开 Magit。

This can be shortened considerably. And it can also be extended into oblivion. Personally, I just like the idea of being able to type magit . into the terminal window, or better yet, have a graphical file manager that does not take ages to load.

这可以大大缩短。同时也可以无限扩展。我个人只是喜欢能够在终端窗口中输入 magit . 的想法,或者更好的是,有一个不会加载很长时间的图形文件管理器。

I can also create domain-specific programs that don’t require and don’t assume text editing. I want to be able to draw SVG inside of a program that respects my ability to program complex interactions. There isn’t an Emacs of graphic design, and I wish that niche were not vacant. I’d be able to find quite a few applications for macros and sequences and composing functions.

我也可以创建特定领域的程序,这些程序不需要也不假设文本编辑功能。我希望能够在尊重我编程复杂交互能力的程序中绘制 SVG。目前还没有图形设计的 Emacs,我希望这个领域不要空缺。我将能够找到许多用于宏、序列和函数组合的应用场景。

Better Languages

更好的语言

The main problem with trying to upstream into the Emacs Savannah repository is that this would impose a great many limitations on what I could do.

试图将代码上游到 Emacs Savannah 仓库的主要问题在于,这会对我能做的事情施加许多限制。

I would have to use C. And C by itself is not a bad language. It is rather simple for what it can do, and conversely it can do quite a bit given its simplicity. But it is not the only choice, and has some great drawbacks.

我不得不使用 C。C 语言本身并不差。它对于能做的事情来说相当简单,反之,鉴于其简单性,它也能做相当多的事情。但它并非唯一的选择,而且存在一些很大的缺点。

It is much easier to do data-oriented design in Zig. Optimising code such that I could e.g. create a DAW that lives inside Emacs would be much easier in Zig, than it would in C.

在 Zig 中进行数据导向设计要容易得多。优化代码,例如创建一个可以运行在 Emacs 内部的 DAW,在 Zig 中会比在 C 中容易得多。

The fact that the incomprehensible jumble of spaghetti that is the Emacs code base does not leak memory and is stable enough that it does not crash if operated days at a time, is not a consequence of the elegance of its design. The new systems in place would have a myriad of bugs, tracking which down would either rest on my shoulders and stretch my time budget, or would be delegated onto the existing maintainers. Neither outcome is particularly good.

Emacs 代码库那令人费解的杂乱结构不会泄露内存,并且足够稳定,可以在连续操作数天的情况下不崩溃,这并非其设计优雅的结果。新系统将存在无数错误,追踪这些错误要么需要我亲自负责并超出我的时间预算,要么会被委托给现有的维护者。无论哪种结果都不理想。

Rust would take care of those issues, and more.

Rust 将解决这些问题,并且更多。

Removing the restriction on having to upstream the code removes the confines of C. I would be able to modularise the work to my heart’s content, write what is sensible in the language sensible for that task and that task alone.

移除必须上传代码的限制,消除了 C 语言的束缚。我将能够随心所欲地模块化工作,用最合适该任务的语言编写最合理的代码。

Further, the process-isolated interaction scheme would allow modules to be written in other languages as well. Emacs lisp is going to be the first and mainly supported language, but it would not be inconceivable to have the C-code of Doom, merely have small adjustments made to render to a window canvas, and use the aforementioned input system instead of its own. At the moment, this is quite hard to do, because one has to think about the multi-modal interactions between Elisp and other objects.

此外,进程隔离的交互方案将允许用其他语言编写模块。Emacs Lisp 将成为第一个和主要支持的语言,但完全有可能将 Doom 的 C 代码,只需进行少量调整以渲染到窗口画布,并使用上述输入系统而不是它自己的系统。目前,这做起来相当困难,因为必须考虑 Elisp 与其他对象之间的多模态交互。

Conclusion 结论

I am essentially writing a brand new text editor from scratch, with the requirement that it used Emacs Lisp and maintained some compatibility with some Emacs packages.

我基本上是从零开始编写一个全新的文本编辑器,要求它使用 Emacs Lisp 并保持与一些 Emacs 包的兼容性。

Eventually that code can be subsumed into Emacs, as happend with XEmacs, and it might die a painful slow death as emacs-ng did. This is a me problem now.

最终,这段代码可以被合并到 Emacs 中,就像 XEmacs 发生的那样,它可能会像 emacs-ng 那样痛苦而缓慢地消亡。现在这是一个我的问题。

I’ll borrow liberally. If you want to play around with it, I shall post a link to the repository when it is public.

我会大量借鉴。如果你想尝试使用它,等它公开后我会发布一个仓库链接。

If you want to play around with the intermediate versions of the code… I’m afraid there’s not much to play with. It was unstable, it barely built and I cannot spend any more time trying to unfuck this jumbled mess. The new code shall not borrow any from the old experiments.

如果你想尝试代码的中间版本……恐怕没什么可尝试的。它极不稳定,几乎无法编译,我无法再花时间试图修复这个混乱的烂摊子。新代码将不会借鉴任何旧实验的代码。

This may sound like bad news, but this can have some positive outcomes. I’m rather unhappy that doing the smaller incremental changes is not going to work… but to be quite frank… this would not have worked, because either Eli Zaretski is operating under constraints that I cannot operate under, or he is blind. In either case, all I’m doing is avoiding the ranks of a plethora of projects that never made it.

这可能听起来像坏消息,但这可能带来一些积极的结果。我相当不高兴,进行小的增量更改并不会奏效……但坦白说……这本来就不会奏效,因为要么是 Eli Zaretski 在我无法承受的限制下工作,要么他就是瞎子。无论如何,我所做的只是在避免大量未能成功的项目。

7 个赞

怎么开始骂人了呢……我也不保留意见了吧,其实从之前的几篇文章就可以看出作者有一种看低所有其它人的工作的趋势:

  • 最开始是骂 GTK 和 PGTK
  • 然后是说用新框架 emacs-reader 就是个 weekend project

    由 tusharhero 指出,这里我有误解。原文来源于 Aleksandr Petrosyan 发在 emacs-devel 上的 Emacs Widget Toolkit

    We commit to maintaining our code but also to providing example projects using our rendering system. Something like the aforementioned Emacs reader should be a weekend project – a tutorial. The code should be documented at least to the standards of the rest of GNU Emacs.

    若这是与 emacs-reader 作者们讨论、达成共识得出的结论的话,那么这点其实没问题。

  • 然后这里骂 Emacs,骂 Eli,中间甚至顺便踢了一脚 EAF

……可行性方面八字没一撇我也不好说,只能从我最近尝试写 editor 的经历来说谨慎不看好。但--我接下来要对人不对事了--Emacs 除开程序之外,社区也是非常重要的一部分,我只能代表我自己希望这种人离 Emacs 社区越远越好。

补充:

原文:

我是觉得已经骂得很难听了。

想到哪说哪:Emacs 和当时 Neovim fork 了 Vim 那时还不同。Neovim 是要把太阳系扩展到银河系,但是所有重写 Emacs 的尝试都是在改引力常数……

5 个赞

通篇只是解释了为什么emacs不好改进,为什么fork重构或者重写要做什么,以及这么做的巨大不确定性罢了,其实并没有"骂人"。总结一句话:历史代码不好动。

2 个赞

我感觉想重构 emacs 的人很多,最后都不了了之了。。。 说起来容易做起来难,没准当ai高度发达以后,可以较为容易的做

1 个赞

要动的历史包袱太多了,这跟从零开始写一个感觉也没差了。。。

作者现在就是想着重新弄一个了…至少他打算重新实现 Elisp 的解释器

如果最后失败了, 也请完成eli, 拜托了 :saluting_face:

guile emacs 不是还在么,为啥又重新发明轮子

1 个赞

工程里面一堆条件编译宏,看代码都费劲

9 个月不动了,都有人觉得这个项目已经死了。

guile emacs 至少已经能用了,fork 一下不也比从头写强

连个能用的东西都没做出来,就在做梦要有啥啥特性,也太务虚了

1 个赞

这是要出现一个类似nvim的东西了么?

除了guile emacs还有用rust写的rune, 正好他不是觉得C语言有点不合适嘛,不过即使这样工程量也还是太多

虽然我也不是特别懂,但是感觉rune最近更新变缓了,就是在自动更新dependency,难度不是一般的大

是的,直接 fork 可能更好。这么看,Schemacs 这个项目比较务实,虽然用的是 Schema,但是作者说会向 Gulie 的 Elisp 解释器上游提交代码。

先做出来点东西再说吧,新建了个文件夹就天天意淫。。

我认为你误解了他们所说的话。 作为合著者 emacs-reader,我可以说 emacs reader 的大部分工作是 破解 Emacs 的限制,找到聪明的方法来做事, 等等。如果做图形化的事情更容易(新的工具包 可能使),该项目确实会简单得多 会花费更少的时间。

事实上,迪维亚和我自己已经与亚历山大讨论过这个问题,并且 这就是他在文章中提到这一点的原因。

2 个赞