feat: all typo candidates for executables

This commit is contained in:
iff 2025-01-06 14:11:42 +01:00
parent 0a799db5e5
commit bf16675d4e
9 changed files with 173 additions and 19 deletions

View file

@ -118,6 +118,10 @@ pub fn best_match_path(typo: &str, executables: &[String]) -> Option<String> {
find_similar(typo, executables, Some(3))
}
pub fn best_matches_path(typo: &str, executables: &[String]) -> Option<Vec<String>> {
find_similars(typo, executables, Some(3))
}
// higher the threshold, the stricter the comparison
// 1: anything
// 2: 50%
@ -143,6 +147,29 @@ pub fn find_similar(typo: &str, candidates: &[String], threshold: Option<usize>)
None
}
pub fn find_similars(typo: &str, candidates: &[String], threshold: Option<usize>) -> Option<Vec<String>> {
let threshold = threshold.unwrap_or(2);
let mut min_distance = typo.chars().count() / threshold + 1;
let mut min_distance_index = vec![];
for (i, candidate) in candidates.iter().enumerate() {
if candidate.is_empty() {
continue;
}
let distance = compare_string(typo, candidate);
if distance == min_distance {
min_distance_index.push(i);
} else if distance < min_distance {
min_distance = distance;
min_distance_index.clear();
min_distance_index.push(i);
}
}
if !min_distance_index.is_empty() {
return Some(min_distance_index.iter().map(|&i| candidates[i].to_string()).collect());
}
None
}
#[allow(clippy::needless_range_loop)]
pub fn compare_string(a: &str, b: &str) -> usize {
let mut matrix = vec![vec![0; b.chars().count() + 1]; a.chars().count() + 1];