atuin_client/
ordering.rs

1use minspan::minspan;
2
3use super::{history::History, settings::SearchMode};
4
5pub fn reorder_fuzzy(mode: SearchMode, query: &str, res: Vec<History>) -> Vec<History> {
6    match mode {
7        SearchMode::Fuzzy => reorder(query, |x| &x.command, res),
8        _ => res,
9    }
10}
11
12fn reorder<F, A>(query: &str, f: F, res: Vec<A>) -> Vec<A>
13where
14    F: Fn(&A) -> &String,
15    A: Clone,
16{
17    let mut r = res.clone();
18    let qvec = &query.chars().collect();
19    r.sort_by_cached_key(|h| {
20        // TODO for fzf search we should sum up scores for each matched term
21        let (from, to) = match minspan::span(qvec, &(f(h).chars().collect())) {
22            Some(x) => x,
23            // this is a little unfortunate: when we are asked to match a query that is found nowhere,
24            // we don't want to return a None, as the comparison behaviour would put the worst matches
25            // at the front. therefore, we'll return a set of indices that are one larger than the longest
26            // possible legitimate match. This is meaningless except as a comparison.
27            None => (0, res.len()),
28        };
29        1 + to - from
30    });
31    r
32}