"以前看 Lisp 代码像解摩斯密码,现在?像在看霓虹灯管搭的乐高。"
------ 一位刚从 7 层嵌套回调中逃生的前端工程师
🔍 一、什么是「彩虹括号」?------ 给括号穿上彩虹衣

简单说:不同嵌套层级的括号,自动用不同颜色高亮。
比如这段 Rust:
rust
fn main() {
let x = foo(bar(baz(1, 2), qux()), 3);
}
→ 最外层 { } 是 蓝色 ,
→ foo(...) 是 橙色 ,
→ bar(...) 是 绿色 ,
→ baz(...) 是 紫色 ......
颜色轮换,层级分明,再也不用靠数括号或靠 IDE 高亮"临时成对"来猜匹配关系!
💡 小知识:
此功能被 Zed 用户"蹲守"超过 3 年 ------ 是 Zed 史上请求量最高的功能 😎
🛠️ 二、技术挑战:为什么"彩虹括号"没那么容易实现?
乍一听:不就是给括号染个色?
但真正落地,要跨过三座大山:
| 方案 | 问题 |
|---|---|
| 依赖语言服务器(LSP) | LSP 协议压根没定义"括号配对/嵌套深度"这类信息;且 90% 的语言服务器不提供此能力 → ❌ 不可扩展 |
| 照搬 VS Code 方案 | VS Code 为实现它,在内存中维护整棵语法树 → 大文件卡顿、内存飙升 → ❌ 不适合 Zed 架构 |
| Zed 的选择 | ✅ 只查询当前可见区域的括号;✅ 拆成小"块"(chunks)懒加载;✅ 复用现有 Tree-sitter 查询体系 |
📌 关键洞察:
用户不需要"绝对精确"的全局嵌套深度------
只要局部视觉区分清晰 ,哪怕深处分界处颜色错一位,人眼也几乎察觉不到 。
"够用就好"的工程哲学,让性能与体验双赢。
🌲 三、核心技术:Tree-sitter + Chunked Query ------ 小而美的组合拳
Zed 早已用 Tree-sitter 做语法高亮、大纲生成等。
而每个语言扩展,都自带一个 brackets.scm 查询文件,比如 Rust 的:
scheme
("(" @open ")" @close)
("[" @open "]" @close)
("{" @open "}" @close)
("<" @open ">" @close)
;; ...省略 closure 和泛型
(("\"" @open "\"" @close) (#set! rainbow.exclude)) ; ← 这行关键!排除字符串引号
👉 这里 (#set! rainbow.exclude) 就是告诉彩虹括号:"引号别染色,免得干扰阅读"。
🧩 智能分块(Chunking):性能的秘密武器
Zed 不再"全文件扫描",而是:
-
把缓冲区(buffer)按 50 行一块 划分;
-
只对当前编辑器可见的块执行 Tree-sitter 括号查询;
-
每块独立计算嵌套深度 → 颜色错位风险被限制在块边界(50 行 ≈ 屏幕 1~2 屏,几乎无感);
-
编辑时只更新变动块,滚动时懒加载新块。
✅ 优点:
- 内存占用低 ------ 无需整棵语法树
- 启动快 ------ 滚动到哪算到哪
- 远程开发友好 ------ 和本地一致(靠 buffer 同步)
⚙️ 四、数据结构设计:极简但高效
核心新增两个字段,放在 Buffer(Zed 的文档模型)里:
rust
pub struct TreeSitterData {
chunks: RowChunks, // 行号分块管理器
brackets_by_chunks: Vec<Option<Vec<BracketMatch<usize>>>>,
}
pub struct BracketMatch<T> {
pub open_range: Range<T>, // 左括号位置
pub close_range: Range<T>, // 右括号位置
pub color_index: Option<usize>, // 颜色序号:0=蓝, 1=橙, 2=绿...
}
- ✅ 数据存在 Buffer,不在 Editor → 多窗口/分屏共享,不重复计算
- ✅ 修改时立刻失效,渲染时才重查 → 编辑流畅不卡顿
- ✅ 复用主题配色 → 7 种"强调色"循环,自动适配深色/浅色主题
🧪 五、测试方法也硬核:可视化断言 + 深度嵌套验证
Zed 团队用一种"可视化测试标记法"验证彩虹逻辑:
rust
fn main<<1()1>> <<1{
let a = one<<2(<<3()3>>, <<3{ <<4()4>> }3>>, <<3()3>>)2>>;
for i in 0..a <<2{
println!<<3("{i}")3>>;
}2>>
}1>>
→ <<n...n>> 表示该对括号应被标为第 n 号颜色(1~7 循环)
→ 测试直接"看图说话",精准验证嵌套逻辑是否正确!
🎛️ 六、如何开启?高度可定制!
默认关闭(避免打扰旧用户),手动开启:
Cmd + ,打开设置- 搜索
Colorize Brackets - 可:
- ✅ 全局开启 / 按语言单独开(比如只给 Rust、JS 开)
- ✅ 排除特定括号(如
"',默认已排除) - ✅ 通过主题定制 7 种颜色

🔮 未来展望:不止于 ()[]{}
Zed 已预留扩展能力:
- ✅ HTML/JSX 标签配对 (
<div>/</div>)技术上已支持,只需在brackets.scm中声明 → 下一版本或由社区贡献! - ✅ 更多 Tree-sitter 查询缓存化(如大纲、inlay hints)------ 借"分块缓存"框架复用
✅ 总结:一次克制而优雅的工程实践
| 维度 | Zed 方案亮点 |
|---|---|
| 性能 | 分块懒加载 + Tree-sitter 局部查询 → 大文件不卡 |
| 架构 | 复用现有 brackets.scm + Buffer 缓存 → 低侵入 |
| 体验 | 颜色轮换 + 排除干扰项 + 主题融合 → 美观不刺眼 |
| 扩展性 | 分块框架可复用 → 为未来功能铺路 |
🎁 Zed 用 3 年时间,把一个"看似简单"的需求,打磨成兼顾性能、架构与用户体验的典范 。
它再次证明:好工具,不在于堆功能,而在于用对的方法,解决真实的痛。