diff --git a/src/files.rs b/src/files.rs index e3facfa..b95b70e 100644 --- a/src/files.rs +++ b/src/files.rs @@ -1,3 +1,5 @@ +use crate::suggestions::find_similar; + pub fn get_path_files() -> Vec { let path = std::env::var("PATH").unwrap(); let path = path.split(':').collect::>(); @@ -16,26 +18,40 @@ pub fn get_path_files() -> Vec { all_executable } -pub fn get_directory_files(input: &str) -> Vec { +pub fn get_best_match_file(input: &str) -> Option { let mut input = input.trim_matches(|c| c == '\'' || c == '"').to_owned(); - let files = loop { + let mut exit_dirs = Vec::new(); + let mut files = loop { match std::fs::read_dir(&input) { Ok(files) => break files, Err(_) => { - if let Some((dirs, _)) = input.rsplit_once('/') { + if let Some((dirs, exit_dir)) = input.rsplit_once('/') { + exit_dirs.push(exit_dir.to_owned()); input = dirs.to_owned(); } else { + exit_dirs.push(input.to_owned()); + input = ".".to_owned(); break std::fs::read_dir("./").unwrap(); } } } }; - let mut all_files = vec![]; - for file in files { - let file = file.unwrap(); - let file_name = file.path().to_str().unwrap().to_owned(); - all_files.push(file_name); + while let Some(exit_dir) = exit_dirs.pop() { + let dir_files = files.filter_map(|file| { + let file = file.unwrap(); + let file_name = file.file_name().into_string().unwrap(); + Some(file_name) + }).collect::>(); + + let best_match = find_similar(&exit_dir, dir_files); + + input = format!("{}/{}", input, best_match.unwrap()); + files = match std::fs::read_dir(&input) { + Ok(files) => files, + Err(_) => return Some(input), + }; } - all_files + + Some(input) } diff --git a/src/suggestions.rs b/src/suggestions.rs index cf5830c..7d0a959 100644 --- a/src/suggestions.rs +++ b/src/suggestions.rs @@ -2,7 +2,7 @@ use regex_lite::Regex; use rule_parser::parse_rules; -use crate::files::{get_directory_files, get_path_files}; +use crate::files::{get_best_match_file, get_path_files}; use crate::shell::{command_output, PRIVILEGE_LIST}; pub fn suggest_command(shell: &str, last_command: &str) -> Option { @@ -105,8 +105,7 @@ fn suggest_typo(typo: &str, candidates: Vec) -> String { } } "file" => { - let files = get_directory_files(typo); - if let Some(suggest) = find_similar(typo, files) { + if let Some(suggest) = get_best_match_file(typo) { suggestion = suggest; } } @@ -115,7 +114,6 @@ fn suggest_typo(typo: &str, candidates: Vec) -> String { } else if let Some(suggest) = find_similar(typo, candidates) { suggestion = suggest; } - suggestion } @@ -158,8 +156,8 @@ fn compare_string(a: &str, b: &str) -> usize { matrix[a.chars().count()][b.chars().count()] } -pub fn confirm_suggestion(shell: &str, command: &str) { - println!{"{}\n", command} +pub fn confirm_suggestion(shell: &str, command: &str, highlighted: &str) { + println!{"{}\n", highlighted} println!("Press enter to execute the suggestion. Or press Ctrl+C to exit."); std::io::stdin().read_line(&mut String::new()).unwrap();