推荐阅读
Zed IDE 发布全新新特性:确实比 VS Code 猛啊!
VS Code 王座动摇?Zed IDE 背靠 亚马逊 正在悄悄"偷家"
最新我用AI开发了自己的第一个博客网站:https://golangai.site ,可前往阅读公众号的文章。
搜
auth internal和internal auth结果一样?这才是人类该有的搜索体验✨
🎯 这个 功能 解决了什么痛点?
一句话总结:以前搜文件必须"按顺序输",现在随便打关键词都能找到目标,像谷歌一样智能!
🐛 以前的尴尬场景
# 想找 internal/auth/login.rs 这个文件
❌ 输入 "auth internal" → 搜不到,或者排很后面
✅ 输入 "internal auth" → 才能正确匹配
# 用户内心:我只是记反了顺序啊喂!😤
💡 这就像:你想找"番茄炒蛋",结果因为说了"炒蛋番茄",餐厅告诉你"本店不卖"🍅🥚
✅ 修复方案:引入 fuzzy_nucleo + 多原子匹配
// 核心改动:把查询按空格拆成独立的 Atom,分别匹配
fn make_atoms(query: &str, smart_case: bool) -> Vec<Atom> {
query
.split_whitespace() // ← 按空格分割
.map(|word| Atom::new(word, case, Normalization::Smart, AtomKind::Fuzzy, false))
.collect()
}
🧠 技术亮点:为什么"多原子匹配"更聪明?
1️⃣ 顺序无关 = 符合人类直觉
# 用户搜索意图:
"我想找一个 同时包含 audio 和 settings 的文件"
# 旧逻辑(顺序敏感):
"audio settings" ✅ 匹配
"settings audio" ❌ 不匹配 → 用户懵了
# 新逻辑(顺序无关):
"audio settings" ✅ 匹配
"settings audio" ✅ 同样匹配 → 用户:舒服了~
🎯 个人观点:好的工具应该适应用户,而不是让用户适应工具。
2️⃣ 文件名优先加分,结果更精准
// 新逻辑:对每个 atom 单独计算文件名匹配加分
fn get_filename_match_bonus(...) -> f64 {
let filename = path.file_name()?;
for atom in query_atoms {
if let Some(score) = atom.score(haystack, matcher) {
total_score += score; // ← 累加每个关键词的匹配度
}
}
total_score / filename.len() // ← 归一化处理
}
效果对比:
| 搜索词 | 旧逻辑结果 | 新逻辑结果 |
|---|---|---|
settings audio | crates/settings_ui/...(目录匹配) | audio_settings.rs ✅(文件名优先) |
nix icon | app-icon-nightly.png | nix.svg ✅(精确文件名) |
3️⃣ 性能优化:Matcher 对象池复用
// 避免频繁创建/销毁 nucleo::Matcher
static MATCHERS: Mutex<Vec<nucleo::Matcher>> = Mutex::new(Vec::new());
pub fn get_matcher(config: nucleo::Config) -> nucleo::Matcher {
let mut matchers = MATCHERS.lock().unwrap();
match matchers.pop() {
Some(mut m) => { m.config = config; m } // ← 复用
None => nucleo::Matcher::new(config), // ← 新建
}
}
💡 小细节:高频搜索场景下,对象池能减少 30%+ 的内存分配开销。
📸 真实效果对比
再增加一个搜索
💬 最后说两句
但它解决了一个每个开发者每天都会遇到的小问题:
"我明明记得关键词,为什么搜不到文件?"
我的观点:优秀的编辑器,不在于功能有多全,而在于是否愿意为那"0.5 秒的搜索犹豫",多写 100 行测试代码。
就像导航软件:
- 能识别"北京火车站"和"火车站北京"是同一个地方
- 能理解"去机场"和"机场 去"是一个意图
好的搜索,应该像懂你的老朋友,而不是死板的搜索引擎。
Zed 这次,把"老朋友"升级了。🎉
