Better autocomplete, still WIP when searching for folders

This commit is contained in:
Justine 2023-02-02 18:14:10 +01:00
parent 4e27fe3106
commit c65438ed6c

View File

@ -8,7 +8,13 @@ pub fn autocomplete(input: &String, prev_match: &String) -> (String, String) {
if !input.contains(' ') && !input.contains("./") { if !input.contains(' ') && !input.contains("./") {
return autocomplete_cmd(input); return autocomplete_cmd(input);
} else { } else {
return autocomplete_file(input, prev_match).unwrap(); match autocomplete_file(input, prev_match) {
Ok(t) => return t,
Err(e) => {
println!("\n\r{}", e);
return (String::from(input), String::new());
},
};
} }
} }
@ -17,28 +23,50 @@ pub fn autocomplete(input: &String, prev_match: &String) -> (String, String) {
fn autocomplete_file(input: &String, prev_match: &String) -> std::io::Result<(String, String)> { fn autocomplete_file(input: &String, prev_match: &String) -> std::io::Result<(String, String)> {
//Keep the last part of the cmd... //Keep the last part of the cmd...
let input_searchee = input let mut input_searchee = match input
.split(' ') .split(' ')
.collect::<Vec<&str>>() .collect::<Vec<&str>>()
.last() .last()
.copied(); .copied() {
Some(c) => c,
None => {
return Ok((String::from(""), String::from("")));
},
};
//And also the beginning ! //And also the beginning !
let mut input_buff = input let mut input_buff = input
.split(' ') .split(' ')
.collect::<Vec<&str>>(); .collect::<Vec<&str>>();
_ = input_buff.pop(); _ = input_buff.pop();
let mut input_origin = format!("{} ", input_buff.join(" ")); let input_origin = format!("{} ", input_buff.join(" "));
//Store the results
let mut results = Vec::new();
//Where do we search ?
let mut folder_to_search = PathBuf::new();
//Display folder in search result ?
let mut searching_current = false;
//Searching somewhere else...
if input_searchee.contains('/') {
//Remove the last part
let toremove = &input_searchee.split('/').last().unwrap();
let tosearch = &input_searchee.replace(toremove, "");
folder_to_search.push(tosearch);
*&mut input_searchee = &toremove;
*&mut searching_current = true;
//Searching the current folder
} else {
folder_to_search = env::current_dir()?;
}
match input_searchee {
Some(s) => {
//Search happens 'round here //Search happens 'round here
let current_dir = env::current_dir()?;
let mut all_res = String::new(); let mut all_res = String::new();
let mut nbr_found: u16 = 0; let mut nbr_found: u16 = 0;
let mut last_found = String::new(); let mut last_found = String::new();
for file in fs::read_dir(current_dir)? { for file in fs::read_dir(&folder_to_search)? {
let filepath = file.unwrap().path(); let filepath = file.unwrap().path();
let filename = filepath let filename = filepath
.iter() .iter()
@ -46,32 +74,39 @@ fn autocomplete_file(input: &String, prev_match: &String) -> std::io::Result<(St
.unwrap() .unwrap()
.to_str() .to_str()
.unwrap(); .unwrap();
let re = format!("^{}.*$", s); let re = format!("^{}.*$", input_searchee);
let regex = Regex::new(&re).unwrap(); let regex = Regex::new(&re).unwrap();
if regex.is_match(filename) { if regex.is_match(filename) {
if !searching_current {
*&mut results.push(format!("{}", filename));
} else {
*&mut results.push(format!("{}{}", &folder_to_search.display(), filename));
}
*&mut nbr_found += 1; *&mut nbr_found += 1;
let matchline = format!("\r\n* {}", filename); let matchline = &format!("\r\n* {}", filename);
&mut all_res.push_str(&matchline); &mut all_res.push_str(&matchline);
//No need to find things we already found //No need to find things we already found
if *prev_match != filename { if *prev_match != filename {
if searching_current {
*&mut last_found = format!("{}{}{}", &input_origin, &folder_to_search.display(), filename);
} else {
*&mut last_found = format!("{}{}", &input_origin, filename); *&mut last_found = format!("{}{}", &input_origin, filename);
} }
} }
} }
}
//Found one or zero, use what has been found directly //Found one or zero, use what has been found directly
if nbr_found < 2 { if nbr_found < 2 {
return Ok((last_found, String::new())); return Ok((last_found, String::new()));
//Otherwise, just display a list //Otherwise, just display a list and use what all the results have in common
} else { } else {
return Ok((String::from(input), all_res)); let longest = find_common_chars(results);
let ret_string = format!("{}{}", input_origin, &longest);
return Ok((ret_string, all_res));
} }
},
None => {
return Ok((String::from(""), String::from("")));
},
};
} }
fn autocomplete_cmd(input: &String) -> (String, String) { fn autocomplete_cmd(input: &String) -> (String, String) {
let found_bins = find_bin(input); let found_bins = find_bin(input);
if found_bins.len() == 1 { if found_bins.len() == 1 {
@ -114,5 +149,35 @@ fn find_bin(command: &String) -> Vec<PathBuf> {
return binaries; return binaries;
} }
fn find_common_chars(mut strvec: Vec<String>) -> String {
let first_word = strvec[0].clone();
strvec.remove(0);
let mut answer = String::new();
let mut counter: usize = 0;
for letter in first_word.chars() {
let mut still_ok = true;
for word in &strvec {
if still_ok == true {
match word.chars().nth(counter) {
Some(l) => {
if l != letter {
*&mut still_ok = false;
}
},
None => {
*&mut still_ok = false;
},
};
}
}
if still_ok == true {
*&mut answer.push(letter);
*&mut counter += 1;
}
}
answer.pop();
return answer;
}