feat: range substitution for typos

This commit is contained in:
iff 2023-08-11 00:41:16 +02:00
parent b991214729
commit 2a5fa8a950
4 changed files with 102 additions and 53 deletions

View file

@ -1,5 +1,5 @@
use std::process::{Stdio, exit};
use std::time::{Instant, Duration};
use std::process::{exit, Stdio};
use std::time::{Duration, Instant};
use regex_lite::Regex;
@ -24,7 +24,7 @@ pub fn suggest_command(shell: &str, last_command: &str, error_msg: &str) -> Opti
let last_command = match PRIVILEGE_LIST.contains(&split_command[0].as_str()) {
true => &last_command[split_command[0].len() + 1..],
false => &last_command,
false => last_command,
};
let suggest = match_pattern(executable, last_command, error_msg, shell);
@ -35,7 +35,7 @@ pub fn suggest_command(shell: &str, last_command: &str, error_msg: &str) -> Opti
return Some(suggest);
}
let suggest = match_pattern("general", &last_command, error_msg, shell);
let suggest = match_pattern("general", last_command, error_msg, shell);
if let Some(suggest) = suggest {
if PRIVILEGE_LIST.contains(&split_command[0].as_str()) {
return Some(format!("{} {}", split_command[0], suggest));
@ -132,31 +132,36 @@ pub fn split_command(command: &str) -> Vec<String> {
split_command
}
fn suggest_typo(typo: &str, candidates: Vec<String>) -> String {
let mut suggestion = typo.to_owned();
if candidates.len() == 1 {
match candidates[0].as_str() {
"path" => {
let path_files = get_path_files();
if let Some(suggest) = find_similar(typo, path_files) {
suggestion = suggest;
fn suggest_typo(typos: &[String], candidates: &[String]) -> String {
let mut path_files = Vec::new();
let mut suggestions = Vec::new();
for typo in typos {
let typo = typo.as_str();
if candidates.len() == 1 {
match candidates[0].as_str() {
"path" => {
if path_files.is_empty() {
path_files = get_path_files();
};
if let Some(suggest) = find_similar(typo, &path_files) {
suggestions.push(suggest);
};
}
}
"file" => {
if let Some(suggest) = get_best_match_file(typo) {
suggestion = suggest;
"file" => {
if let Some(suggest) = get_best_match_file(typo) {
suggestions.push(suggest);
}
}
_ => {}
}
_ => {}
} else if let Some(suggest) = find_similar(typo, candidates) {
suggestions.push(suggest);
}
} else if let Some(suggest) = find_similar(typo, candidates) {
suggestion = suggest;
}
suggestion
suggestions.join(" ")
}
pub fn find_similar(typo: &str, candidates: Vec<String>) -> Option<String> {
pub fn find_similar(typo: &str, candidates: &[String]) -> Option<String> {
let mut min_distance = 10;
let mut min_distance_index = None;
for (i, candidate) in candidates.iter().enumerate() {