Hacker News 中文摘要

RSS订阅

好吧,我自己建个文本编辑器 -- Fine, I'll build my own text editor

作者认为现代软件质量下降,决定自己构建文本编辑器。他尝试用Canvas元素实现基础编辑功能,包括光标定位、键盘移动、高亮当前行、文本输入和光标动画,并提供了交互演示。

正文

好的,这是根据您的要求,对原文进行中文重述后的版本:

标题:好吧,我自己来写个文本编辑器!

作者在之前的一篇文章中感叹“像Sublime Text那样的编辑器已经没有了”,这引起了很多人的共鸣。作者自嘲说,现在的软件很糟糕,而自己恰好擅长做“糟糕的软件”,于是萌生了自己动手写一个文本编辑器的想法。

作者指出,VS Code是基于Monaco Editor构建的,而Monaco Editor本质上是一个由大量<div>元素构成的复杂结构。作者因为旧款Mac性能不足,很晚才用上VS Code,直到换了苹果芯片的电脑才解决这个问题。因此,作者认为自己有足够的空间去尝试和犯错。

Canvas方案

作者的第一个实验是在<canvas>元素上渲染所有内容。但这种方式存在明显问题:缺乏交互性,且CPU需要持续高负荷工作来渲染画面。作者列出了“最小可行”功能并实现了,包括:点击定位光标、方向键移动光标、高亮当前行、输入文字以及光标动画。

然而,Canvas方案无法提供任何现成的功能,作者还缺少文本选择、撤销/重做、多行粘贴和溢出滚动等关键特性。特别是溢出滚动,作者认为实现自定义滚动条太麻烦,于是“作弊”使用了原生浏览器的溢出滚动,用一个隐藏的<div>来匹配画布文本大小,并利用其滚动位置来计算Canvas的渲染偏移。

尽管这个方案进展顺利,但作者感到沮丧,因为<canvas>元素对无障碍访问完全不友好。继续添加功能也无法解决这个根本问题。

Contenteditable方案

于是作者想到了更好的办法:不在<canvas>上渲染文本,而是直接在用于滚动的<div>中渲染,并利用contenteditable属性使其可编辑。该属性的plaintext-only值非常适合代码编辑,所有内容都保持在一个文本节点内。作者还特别指出,必须禁用spellcheck等属性,以避免输入延迟,并为此花费了数天时间排查。

使用contenteditable可以免费获得浏览器的原生文本选择、撤销历史和无障碍功能。作者利用Selection API来获取光标位置,并继续渲染自定义光标。但作者发现,当字符数超过一定量时,Chromium内核的浏览器会出现奇怪的性能问题,表现不如WebKit内核。

Textarea方案

最后,作者尝试了更简单的<textarea>方案。事实证明,对于长文本,<textarea>的性能远优于contenteditable。作者在最终的演示中加入了语法高亮功能。由于<textarea>无法使用CSS高亮,作者额外添加了一层<div>来为可见行应用高亮。

作者也提到了两个新的API:OpaqueRange API可以为<textarea>解锁自定义高亮,而EditContext API则能改善<canvas>的输入体验。作者认为,过多的CSS高亮是另一个性能瓶颈,更稳健的解决方案是使用Tree-sitter生成语法树,只为可见行生成高亮。

总结

作者总结道,目前的成果看起来像是一个完成了90%外观、但只有1%功能的文本编辑器。从当前阶段到完成一个完整的编辑器,还有大量细节工作要做,比如处理Tab缩进。作者承认,他的演示代码未经优化,在无障碍方面也远非完美,但至少没有从一开始就陷入像Canvas那样的困境。作者决定将这个项目暂时搁置,留待日后有闲时再继续。

最后,作者以一个关于JavaScript字符串和文本范围处理Unicode字符的代码示例作为结尾,提醒大家注意UTF-16编码可能引入的bug。

评论

根据评论内容,总结如下:

主要观点与论据:

  1. 文本编辑是“已解决”的问题,但仍有争议

    • 支持者认为Emacs/Vim已足够,新工具是冗余(anon291: "Text editing is a solved problem. Most of the supposed advantages... is just a configuration of vim or emacs")。
    • 反对者指出远程编辑、LSP支持等新需求未解决(self_awareness: "It's about remote editing, LSP support")。
  2. 构建文本编辑器的挑战与乐趣

    • 技术难点:性能、渲染、光标处理(rfgplk: "most text editors... you can very easily start seeing noticeable lag";swiftcoder: "Canvas-based text editor is definitely hard-mode")。
    • 学习价值:深入理解输入/渲染(Driftbench: "It's a rabbit hole, but you learn so much about rendering and input")。
    • 个人项目:许多开发者自建编辑器(joefreeman: "I've also been building my own editor - it's been fun")。
  3. 对现有工具的评价

    • 批评性能:多数编辑器在大型文件上表现糟糕(rfgplk: "for editing buffers >1MB, 99% of them are unusable")。
    • 怀念经典:NEdit、Kate等被提及(vintermann: "I still miss NEdit... it was tiny")。
    • 推荐替代:CodeMirror 6、Clobber等(qbane: "Hope the author finds CodeMirror 6 to be a solid foundation")。
  4. 幽默与自嘲

    • 开发者常重复造轮子(jdw64: "A great programmer should try building a text editor";alwaysmrno: "text editors are to computer engineers what trains are to mechanical engineers")。

平衡性总结:
评论呈现两极分化:一方认为文本编辑已成熟,新工具是冗余;另一方强调性能、新需求(如LSP)和自建项目的学习价值。多数评论认可构建编辑器的技术挑战,但批评现有工具的性能缺陷。