
你不会为了自己付出的真心而感到后悔
“以前看 Lisp 代码像解摩斯密码,现在?像在看霓虹灯管搭的乐高。” —— 一位刚从 7 层嵌套回调中逃生的前端工程师

简单说:不同嵌套层级的括号,自动用不同颜色高亮。
比如这段 Rust:
fnmain(){
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 查询体系 |
📌 关键洞察: 用户不需要“绝对精确”的全局嵌套深度—— 只要局部视觉区分清晰,哪怕深处分界处颜色错一位,人眼也几乎察觉不到。 “够用就好”的工程哲学,让性能与体验双赢。
Zed 早已用 Tree-sitter 做语法高亮、大纲生成等。
而每个语言扩展,都自带一个 brackets.scm 查询文件,比如 Rust 的:
("(" @open ")" @close)
("[" @open "]" @close)
("{" @open "}" @close)
("<" @open ">" @close)
;; …省略 closure 和泛型
(("\"" @open "\"" @close) (#set! rainbow.exclude)) ; ← 这行关键!排除字符串引号👉 这里 (#set! rainbow.exclude) 就是告诉彩虹括号:“引号别染色,免得干扰阅读”。
Zed 不再“全文件扫描”,而是:
✅ 优点: - 内存占用低 —— 无需整棵语法树 - 启动快 —— 滚动到哪算到哪 - 远程开发友好 —— 和本地一致(靠 buffer 同步)
核心新增两个字段,放在 Buffer(Zed 的文档模型)里:
pubstructTreeSitterData{
chunks:RowChunks,// 行号分块管理器
brackets_by_chunks:Vec<Option<Vec<BracketMatch<usize>>>>,
}
pubstructBracketMatch<T>{
pub open_range:Range<T>,// 左括号位置
pub close_range:Range<T>,// 右括号位置
pub color_index:Option<usize>,// 颜色序号:0=蓝, 1=橙, 2=绿...
}Zed 团队用一种“可视化测试标记法”验证彩虹逻辑:
fnmain«1()1» «1{
let a = one«2(«3()3», «3{ «4()4» }3», «3()3»)2»;
for i in0..a «2{
println!«3("{i}")3»;
}2»
}1»→ «n…n» 表示该对括号应被标为第 n 号颜色(1~7 循环)
→ 测试直接“看图说话”,精准验证嵌套逻辑是否正确!
默认关闭(避免打扰旧用户),手动开启:
Cmd + , 打开设置Colorize Brackets"',默认已排除)
()[]{}Zed 已预留扩展能力:
brackets.scm 中声明 → 下一版本或由社区贡献!分块懒加载 + Tree-sitter 局部查询 → 大文件不卡🎁 Zed 用 3 年时间,把一个“看似简单”的需求,打磨成兼顾性能、架构与用户体验的典范。 它再次证明:好工具,不在于堆功能,而在于用对的方法,解决真实的痛。