Match full path when query contains spaces
Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
be24e58926
commit
f934370e7f
1 changed files with 47 additions and 2 deletions
|
@ -6,6 +6,8 @@ use std::{ops::Range, sync::Arc};
|
|||
pub struct Outline<T> {
|
||||
pub items: Vec<OutlineItem<T>>,
|
||||
candidates: Vec<StringMatchCandidate>,
|
||||
path_candidates: Vec<StringMatchCandidate>,
|
||||
path_candidate_prefixes: Vec<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -18,6 +20,30 @@ pub struct OutlineItem<T> {
|
|||
|
||||
impl<T> Outline<T> {
|
||||
pub fn new(items: Vec<OutlineItem<T>>) -> Self {
|
||||
let mut path_candidates = Vec::new();
|
||||
let mut path_candidate_prefixes = Vec::new();
|
||||
let mut item_text = String::new();
|
||||
let mut stack = Vec::new();
|
||||
|
||||
for (id, item) in items.iter().enumerate() {
|
||||
if item.depth < stack.len() {
|
||||
stack.truncate(item.depth);
|
||||
item_text.truncate(stack.last().copied().unwrap_or(0));
|
||||
}
|
||||
if !item_text.is_empty() {
|
||||
item_text.push(' ');
|
||||
}
|
||||
path_candidate_prefixes.push(item_text.len());
|
||||
item_text.push_str(&item.text);
|
||||
stack.push(item_text.len());
|
||||
|
||||
path_candidates.push(StringMatchCandidate {
|
||||
id,
|
||||
string: item_text.clone(),
|
||||
char_bag: item_text.as_str().into(),
|
||||
});
|
||||
}
|
||||
|
||||
Self {
|
||||
candidates: items
|
||||
.iter()
|
||||
|
@ -28,13 +54,21 @@ impl<T> Outline<T> {
|
|||
string: item.text.clone(),
|
||||
})
|
||||
.collect(),
|
||||
path_candidates,
|
||||
path_candidate_prefixes,
|
||||
items,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn search(&self, query: &str, executor: Arc<Background>) -> Vec<StringMatch> {
|
||||
let query = query.trim_start();
|
||||
let is_path_query = query.contains(' ');
|
||||
let mut matches = fuzzy::match_strings(
|
||||
&self.candidates,
|
||||
if is_path_query {
|
||||
&self.path_candidates
|
||||
} else {
|
||||
&self.candidates
|
||||
},
|
||||
query,
|
||||
true,
|
||||
100,
|
||||
|
@ -47,8 +81,19 @@ impl<T> Outline<T> {
|
|||
let mut tree_matches = Vec::new();
|
||||
|
||||
let mut prev_item_ix = 0;
|
||||
for string_match in matches {
|
||||
for mut string_match in matches {
|
||||
let outline_match = &self.items[string_match.candidate_id];
|
||||
|
||||
if is_path_query {
|
||||
let prefix_len = self.path_candidate_prefixes[string_match.candidate_id];
|
||||
string_match
|
||||
.positions
|
||||
.retain(|position| *position >= prefix_len);
|
||||
for position in &mut string_match.positions {
|
||||
*position -= prefix_len;
|
||||
}
|
||||
}
|
||||
|
||||
let insertion_ix = tree_matches.len();
|
||||
let mut cur_depth = outline_match.depth;
|
||||
for (ix, item) in self.items[prev_item_ix..string_match.candidate_id]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue