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

Piotr Osiewicz and Bennet Bo created

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>

Change summary

crates/language/src/outline.rs | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

Detailed changes

crates/language/src/outline.rs 🔗

@@ -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