Autocompletion is not easy

This commit is contained in:
Justine Pelletreau
2023-02-03 18:09:31 +01:00
parent 9d5fd0428c
commit d2eb54d369

View File

@ -3,6 +3,11 @@ use regex::Regex;
use std::path::PathBuf; use std::path::PathBuf;
use std::{env, fs}; use std::{env, fs};
#[derive(Debug)]
enum SearchType {
FileSearch,
CmdSearch,
}
///Contains all necesseary info and methods to perform an autocomplete search. ///Contains all necesseary info and methods to perform an autocomplete search.
///Built from user input. ///Built from user input.
@ -17,12 +22,16 @@ pub struct Search {
searchee: String, searchee: String,
//Set to true if we are searching in current folder. //Set to true if we are searching in current folder.
local_search: bool, local_search: bool,
//the kind of search
search_type: SearchType,
} }
impl Search { impl Search {
///Returns a Search instance, taking the command line input. ///Returns a Search instance, taking the command line input.
pub fn build(input: &String) -> std::io::Result<Search> { pub fn build(input: &String) -> std::io::Result<Search> {
let search_type = Self::discriminate_search_type(input);
//Getting cmd and searched string //Getting cmd and searched string
let mut words = input.split(' ').collect::<Vec<&str>>(); let mut words = input.split(' ').collect::<Vec<&str>>();
let buff_searchee = String::from(*words.last().unwrap_or(&"")); let buff_searchee = String::from(*words.last().unwrap_or(&""));
@ -69,6 +78,7 @@ impl Search {
search_path: search_path, search_path: search_path,
searchee: searchee, searchee: searchee,
local_search: local, local_search: local,
search_type: search_type,
}; };
return Ok(s); return Ok(s);
} }
@ -76,25 +86,14 @@ impl Search {
///Performs the search and returns (most likely result, result lines to display) ///Performs the search and returns (most likely result, result lines to display)
///A found file is preferred to a found command ///A found file is preferred to a found command
pub fn autocomplete(&self) -> (String, String) { pub fn autocomplete(&self) -> (String, String) {
let (found_cmd, found_cmd_lines) = autocomplete_cmd(&self.searchee); let (res, res_lines) = match &self.search_type {
let (found_file, found_file_lines) = match autocomplete_file(&self){ SearchType::CmdSearch => autocomplete_cmd(&self.searchee),
SearchType::FileSearch => match autocomplete_file(&self) {
Ok(t) => t, Ok(t) => t,
Err(_) => (String::new(), String::new()), Err(_) => (String::new(), String::new()),
}
}; };
let mut res_lines = String::new();
if found_file.len() > 0 {
res_lines = found_file_lines.clone();
} else {
res_lines = found_cmd_lines.clone();
}
let mut res = String::new();
if found_file.len() > 0 {
res = String::from(&found_file);
} else {
res = String::from(&found_cmd);
}
if !&self.local_search { if !&self.local_search {
let return_val = format!("{} {}{}", &self.command, &self.search_path.display(), res); let return_val = format!("{} {}{}", &self.command, &self.search_path.display(), res);
return(return_val, res_lines); return(return_val, res_lines);
@ -103,13 +102,32 @@ impl Search {
return(return_val, res_lines); return(return_val, res_lines);
} }
} }
fn discriminate_search_type(input: &String) -> SearchType {
let tamere = input.clone();
let mut a = tamere.split(" ").collect::<Vec<&str>>();
let y = String::from(a.pop().unwrap());
let mut x = String::from(a.join(" ").trim());
if x.len() > 0 {
x.push_str(" ")
};
if x.pop() == Some(' ') {
if x.pop() == Some('|') {
return SearchType::CmdSearch;
} else {
return SearchType::FileSearch;
}
} else {
return SearchType::CmdSearch;
}
}
} }
///Look for a file using the string after the last space in the input, ///Look for a file using the string after the last space in the input,
///in the current folder. ///in the current folder.
fn autocomplete_file(search: &Search) -> std::io::Result<(String, String)> { fn autocomplete_file(search: &Search) -> std::io::Result<(String, String)> {
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();
@ -184,7 +202,9 @@ fn autocomplete_cmd(input: &String) -> (String, String) {
return (res, list); return (res, list);
} else { } else {
let mut all_res = String::new(); let mut all_res = String::new();
let mut counter = 0;
for path in found_bins { for path in found_bins {
if counter < 40 {
let buff = String::from(path let buff = String::from(path
.iter() .iter()
.last() .last()
@ -193,6 +213,12 @@ fn autocomplete_cmd(input: &String) -> (String, String) {
.unwrap()); .unwrap());
let res_line = format!("* {}\r\n", buff); let res_line = format!("* {}\r\n", buff);
all_res.push_str(&res_line); all_res.push_str(&res_line);
counter += 1;
}
else {
all_res.push_str("[...]\r\n");
break;
}
} }
let first_res = String::from(input); let first_res = String::from(input);
return(first_res, all_res) return(first_res, all_res)
@ -205,7 +231,8 @@ fn autocomplete_cmd(input: &String) -> (String, String) {
fn find_bin(command: &String) -> Vec<PathBuf> { fn find_bin(command: &String) -> Vec<PathBuf> {
let re = format!("^{}.*", command); let re = format!("^{}.*", command);
let re = Regex::new(&re).unwrap(); let re = Regex::new(&re).unwrap();
let binaries: Vec<PathBuf> = which_re(re).unwrap().collect(); let mut binaries: Vec<PathBuf> = which_re(re).unwrap().collect();
binaries.sort();
return binaries; return binaries;
} }