只读字符很重要。
Readonly Characters Are a Big Deal

原始链接: https://matklad.github.io/2025/11/10/readonly-characters.html

作者将UNIX管道的批处理性质与Emacs交互式、可变文本缓冲区进行对比,将Emacs的用户体验——特别是Magit——定位为一种强大的UI范式。一个关键的见解是Emacs能够在缓冲区内定义只读*范围*,从而实现双向交互。 这通过编辑器内的终端来举例说明:命令行可由用户编辑,但在提交后被编辑器视为只读,而状态更新由编辑器控制,不应允许用户编辑。命令输出理想情况下应允许协作编辑。 作者认为这种细粒度的只读控制对于构建交互式工具至关重要,而VS Code的编辑器(Monaco)缺乏这种能力,因为它失去了这种特性。他们提出“对持久只读属性的支持”作为评估编辑器是否适合于像Magit这样复杂、交互式应用程序的关键测试,并以Emacs的`M-x`中回显的只读命令为例。

## 黑客新闻讨论:只读字符与终端历史 一篇关于“只读字符”的链接引发了黑客新闻的讨论,深入探讨了不同终端和文本编辑方式的历史和权衡。 对话的核心在于旧系统(如3270终端)的效率,它们发送文本块,仅在确认后传输编辑,与更现代的逐字符更新方法(如VT终端)进行对比。虽然3270对于处理能力有限的大型机来说效率很高,但它难以处理异步更新。 用户还讨论了使用转义序列来管理csh和vi等shell中的输入模式的技术,以及在设备上缓冲的好处。讨论扩展到Vim和Neovim等现代编辑器,指出它们当前的功能(textprops、extmarks)在创建真正只读区域方面存在局限性,无法与Emacs的功能相媲美,并表达了对更多以缓冲区为中心的界面的渴望。
相关文章

原文

I like Emacs UX as exemplified by Magit. I consider it to be a user interface paradigm on the same footing as UNIX pipes: An Engine for an Editor

Pipes give you 1D read-only streams of characters which excel at batch processing. Emacs is all about interactive mutable 2D buffers of attributed text.

Today I realized that an important feature of Emacs text buffers is read-only characters (manual).

Like in any editor, you can mark an entire Emacs buffer as read-only. But you also can mark individual substrings read-only, so that you can edit anywhere except specific ranges

This is a useful feature for bidirectional interaction. Consider the in-editor terminal I am using currently, which looks like this:

./zig/zig build fuzz -- message_bus

= time: 3s =

info(fuzz): Fuzz seed = 2355780251053186744
info(message_bus_fuzz): command weight: reserved = 0
info(message_bus_fuzz): command weight: ping = 0
info(message_bus_fuzz): command weight: pong = 0
info(message_bus_fuzz): command weight: ping_client = 0
info(message_bus_fuzz): command weight: pong_client = 0
info(message_bus_fuzz): command weight: request = 0
info(message_bus_fuzz): command weight: prepare = 37
info(message_bus_fuzz): command weight: prepare_ok = 0

The first line is the command to execute, this is typed by me manually, and then I hit a “submit” shortcut to actually run the command. Then goes the status line, which shows how long the command has been running so far and the exit code (when the command terminates). The status line is determined by the “terminal” itself. Finally, there’s output of the command itself, updated live.

In this sort of the interface, command is modifiable by the user, but is read-only for the editor. Status is the opposite — the editor updates it every second, but the user should be prevented from touching it. And the output can be CRDT-style edited by both parties (I often find it useful to edit the output in place before pasting it elsewhere).

Sadly, in VS Code I can’t prevent the user from editing the status, so my implementation is a bit janky, and this, I think, goes to the core of why I don’t see VS Code as a great platform for the kind of interactive tools I want to write.

Read-only ranges are hard to implement! Text editing hates you as is, but this feature requires tracking text attributes in an intelligent way under modifications (see sticky properties), and also feeds back into modifications themselves! No wonder Monaco, the editor engine underlying VS Code, lost this ability at some point.

Still, I feel like “does it support sticky read-only attribute?” is a good litmus test to check if an editor can support interactive applications a-la Magit seamlessly. Ever used M-x? Well, the echoed M-x in the minibuffer is readonly!

联系我们 contact @ memedata.com