Autocompletion is not easy
This commit is contained in:
@ -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),
|
||||||
Ok(t) => t,
|
SearchType::FileSearch => match autocomplete_file(&self) {
|
||||||
Err(_) => (String::new(), String::new()),
|
Ok(t) => t,
|
||||||
|
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,15 +202,23 @@ 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 {
|
||||||
let buff = String::from(path
|
if counter < 40 {
|
||||||
.iter()
|
let buff = String::from(path
|
||||||
.last()
|
.iter()
|
||||||
.unwrap()
|
.last()
|
||||||
.to_str()
|
.unwrap()
|
||||||
.unwrap());
|
.to_str()
|
||||||
let res_line = format!("* {}\r\n", buff);
|
.unwrap());
|
||||||
all_res.push_str(&res_line);
|
let res_line = format!("* {}\r\n", buff);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user