timzaak / blog

8 stars 1 forks source link

编辑器研究 #118

Closed timzaak closed 1 month ago

timzaak commented 2 months ago

在研究了一圈 #116 后,很自然的跳到编辑器开发 lapce

整理一下小技巧:

  1. lapce-core/{build.rs|src/meta.rs} 将编译变量代码化。
  2. 通过消息来解耦 crossbeam。
  3. remote proxy 下载采用脚本处理,很多地方也是基于shell 脚本来处理。 但异常情况的 recover 不好搞。

代码语法树分析用 tree_sitter 来做。文本编辑用 Rope 结构。

远程与本地

中间加了一层 rpc-proxy,抹平 local/ remote rpc。 remote 目前做了ssh、wsl,后期可以扩展成服务器。 ssh remote 部分没有看到网络卡顿时的处理情况。

渲染

搞出了 floem GUI,里面有各种各样的GUI 组件。 floem 具体写在 #117

Terminal 实现

基于 alacritty 管理 Terminal 编辑状态,渲染基于 floem 搞。原因可能在于一个窗口,无法简单的兼容多个渲染引擎?

插件

自搞了个(Plugin Server Protocol)协议,模仿vs code LSP,基于 wasmtime 做逻辑,用 channel 解耦。 插件注册事件到 PluginCatalog,根据事件进行分发。 至于 lsp 插件,是下载二进制包,由主程序启动,例如 rust 是走 rust-analyser server(这样也容易兼容很多其他包吧)。

静态语言有个问题,就是挂插件的时候,如何能做到低开销通信?

工程化

很多都基于自己的需求做了二开。

timzaak commented 2 months ago

zed 另一款基于 Rust 的编辑器, 编辑状态使用了tree-sitter 来进行源码文件解析和语法树生成。 号称最快,但目前看其原因是

  1. 在 Mac 是使用了 metal 直写,没有用2D render 引擎 中间层。
  2. rope 的改造。

目前 Linux 快支持了,参考官方blog: zed-decoded-linux-when

远程

websocket + protobuf,估计是为了以后的浏览器兼容。

渲染

blade, mac Metal。 构建了 gpui, 类似 floem

Terminal 实现

基于 alacritty 管理 Terminal 编辑状态,渲染自行处理。

插件

现在还不支持插件,不过已在roadmap 中。

timzaak commented 1 month ago

Helix 基于 Terminal 的编辑器,也是 Rust 编写,不支持鼠标事件。 使用Tokio 作为异步运行时,代码风格是让人阅读的明白,没那么多花里胡哨的东西,相比于有窗口的编辑器,可以不用管GPU渲染的东西。 基于 tree-sitter 做着色、源码 AST。

Helix 目前尚无 插件、远程功能。

入口:helix-term/src/main.rs。

跨平台

  1. 采用 etcetera 解决配置、cache 等目录问题。
  2. 采用 crossterm、tui fork 解决 dec/ansi 跨平台输出,tui 的继任者:ratatui

小技巧:

  1. version 等编译变量通过 build.rs cargo:rustc-env 注入。
timzaak commented 1 month ago

历史功能

分为 Location 跳转历史,编辑历史。 Location 跳转,一般包含窗口跳转,光标跳转。可用 Vec 记录。 编辑历史使用 Rope 结构来做。Xi-Editor 关于 Rope 讲解

Helix 有独立实现, lapce 的拆分进 Floem 的 TextEditor 的实现

数据接口

Zed 关于文本编辑数据结构的 讲解, more than Rope: SumTree

保存文件

没有用到随机写功能,直接全量写入。

timzaak commented 1 month ago

总结

lapce 完成度更高一些,但抛弃到GPU渲染,还是阅读 Helix 源码更有助于理解编辑器实现。 活跃度上是 Zed 高,PR能力超强。

编辑器实现难度很大,几个项目的 BUG 列表都很长。