outline: Match on full item path in Outline::find_most_similar (#16206)

Previously, we were only looking at a simple syntax node name at a time
and not the full path to an item. E.g. in a rust-toolchain.toml file:
```rs
[toolchain]
targets = [ "x86_64-apple-darwin", "aarch64-apple-darwin", "x86_64-unknown-linux-gnu", "wasm32-wasi" ]
```
When matching against a query "toolchain targets" from the Assistant,
we'd try to match it against "toolchain" and "targets" and not against
"toolchain targets" - we only look at the name of the innermost node and
not it's full path.
I'd expect it to significantly improve precision of outline item
matching.

Release Notes:

- N/A

Co-authored-by: Bennet Bo <bennet@zed.dev>
This commit is contained in:
Piotr Osiewicz 2024-08-14 14:03:28 +02:00 committed by GitHub
parent b7dcd4e4d6
commit e28681c27e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -88,16 +88,18 @@ impl<T> Outline<T> {
pub fn find_most_similar(&self, query: &str) -> Option<&OutlineItem<T>> {
const SIMILARITY_THRESHOLD: f64 = 0.6;
let (item, similarity) = self
.items
let (position, similarity) = self
.path_candidates
.iter()
.map(|item| {
let similarity = strsim::normalized_levenshtein(&item.text, query);
(item, similarity)
.enumerate()
.map(|(index, candidate)| {
let similarity = strsim::normalized_levenshtein(&candidate.string, query);
(index, similarity)
})
.max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap())?;
if similarity >= SIMILARITY_THRESHOLD {
let item = self.items.get(position)?;
Some(item)
} else {
None