From aa9cbb323d8690c72aa18bf62931b1cafb1a0735 Mon Sep 17 00:00:00 2001 From: Justine Date: Tue, 7 Feb 2023 01:34:43 +0100 Subject: [PATCH] Fiddled more with autocompletion --- src/shell/autocomplete.rs | 131 +++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 58 deletions(-) diff --git a/src/shell/autocomplete.rs b/src/shell/autocomplete.rs index 4e9f50e..4577758 100644 --- a/src/shell/autocomplete.rs +++ b/src/shell/autocomplete.rs @@ -2,6 +2,7 @@ use which::which_re; use regex::Regex; use std::path::PathBuf; use std::{env, fs}; +use termion::color; #[derive(Debug)] enum SearchType { @@ -36,7 +37,10 @@ impl Search { let mut words = input.split(' ').collect::>(); let buff_searchee = String::from(*words.last().unwrap_or(&"")); words.pop(); - let input_cmd = words.join(" "); + let mut input_cmd = words.join(" "); + if input_cmd.len() > 0 { + input_cmd.push_str(" "); + } //Are we looking in a specific path ? //eg. am I doing cat mystuff.txt or cat folder/subfolder/mystuff.txt ? @@ -87,7 +91,7 @@ impl Search { ///A found file is preferred to a found command pub fn autocomplete(&self) -> (String, String) { let (mut res, res_lines) = match &self.search_type { - SearchType::CmdSearch => autocomplete_cmd(&self.searchee), + SearchType::CmdSearch => autocomplete_cmd(&self.searchee, &self), SearchType::FileSearch => match autocomplete_file(&self) { Ok(t) => t, Err(_) => (String::new(), String::new()), @@ -103,6 +107,11 @@ impl Search { fn discriminate_search_type(input: &String) -> SearchType { let tamere = input.clone(); + //./Means we want to execute something in place + if input.starts_with("./") || input.starts_with(" ./") { + return SearchType::FileSearch; + } + let mut a = tamere.split(" ").collect::>(); let _y = String::from(a.pop().unwrap()); let mut x = String::from(a.join(" ").trim()); @@ -110,6 +119,7 @@ impl Search { x.push_str(" ") }; + if x.pop() == Some(' ') { if x.pop() == Some('|') { return SearchType::CmdSearch; @@ -126,68 +136,72 @@ impl Search { ///Look for a file using the string after the last space in the input, ///in the current folder. fn autocomplete_file(search: &Search) -> std::io::Result<(String, String)> { - let mut all_res = String::new(); - let mut nbr_found: u16 = 0; - let mut last_found = String::new(); - let mut results = Vec::new(); + let mut all_res = String::new(); + let mut nbr_found: u16 = 0; + let mut last_found = String::new(); + let mut results = Vec::new(); - for file in fs::read_dir(search.search_path.clone())? { - let filepath = file.unwrap().path(); - let filename = filepath - .iter() - .last() - .unwrap() - .to_str() - .unwrap(); - let re = format!("^{}.*$", search.searchee); - let regex = Regex::new(&re).unwrap(); - if regex.is_match(filename) { - if search.local_search { - *&mut results.push(format!("{}", filename)); - } else { - *&mut results.push(format!("{}{}", &search.search_path.display(), filename)); - } - *&mut nbr_found += 1; - let matchline = &format!("\r\n* {}", filename); - &mut all_res.push_str(&matchline); - - //if what we found is a folder, we add an / after - let fullpath = format!("{}/{}", &search.search_path.display(), filename); - let mut ending = String::new(); - match fs::metadata(fullpath) { - Ok(e) => { - //Will be added to the end of the result - if e.is_dir() { - *&mut ending.push_str("/"); - } - }, - Err(_) => (), - }; - *&mut last_found = format!("{}{}", filename, ending); + for file in fs::read_dir(search.search_path.clone())? { + let filepath = file.unwrap().path(); + let filename = filepath + .iter() + .last() + .unwrap() + .to_str() + .unwrap(); + let re = format!("^{}.*$", search.searchee); + let regex = Regex::new(&re).unwrap(); + if regex.is_match(filename) { + if search.local_search { + *&mut results.push(format!("{}", filename)); + } else { + *&mut results.push(format!("{}{}", &search.search_path.display(), filename)); } - } + *&mut nbr_found += 1; - //Handle returning the longest sequence of characters between two or more matching files - if nbr_found > 1 { - let longest = find_common_chars(results); - *&mut last_found = longest; + //if what we found is a folder, we add an / after + let fullpath = format!("{}/{}", &search.search_path.display(), filename); + let mut ending = String::new(); + let mut matchline = format!("\r\n{}", filename); + match fs::metadata(fullpath) { + Ok(e) => { + //Will be added to the end of the result + if e.is_dir() { + *&mut matchline = format!("{}{}/{}", + color::Fg(color::Green), + matchline, + color::Fg(color::Reset) + ); + *&mut ending.push_str("/"); + } + }, + Err(_) => (), + }; + &mut all_res.push_str(&matchline); + *&mut last_found = format!("{}{}", filename, ending); } + } - //Handle the path when tabbing in a long path, zsh-like - //then return the value - let xxx = &search.search_path.clone().into_os_string().into_string().unwrap(); - if !&search.local_search && !&last_found.contains(&xxx.as_str()) { - let return_val = format!("{} {}{}", &search.command, &search.search_path.display(), last_found); - return Ok((return_val, all_res)); - } else { - let return_val = format!("{} {}", &search.command, last_found); - return Ok((return_val, all_res)); - } - + //Handle returning the longest sequence of characters between two or more matching files + if nbr_found > 1 { + let longest = find_common_chars(results); + *&mut last_found = longest; + } + + //Handle the path when tabbing in a long path, zsh-like + //then return the value + let xxx = &search.search_path.clone().into_os_string().into_string().unwrap(); + let mut return_val = String::new(); + if !&search.local_search && !&last_found.contains(&xxx.as_str()) { + *&mut return_val = format!("{}{}{}", &search.command, &search.search_path.display(), last_found); + } else { + *&mut return_val = format!("{}{}", &search.command, last_found); + } + return Ok((return_val, all_res)); } -fn autocomplete_cmd(input: &String) -> (String, String) { +fn autocomplete_cmd(input: &String, search: &Search) -> (String, String) { let found_bins = find_bin(input); if found_bins.len() == 1 { let aaa = found_bins.clone(); @@ -195,7 +209,7 @@ fn autocomplete_cmd(input: &String) -> (String, String) { .iter() .last() .unwrap(); - let res_string = String::from(bbb.to_str().unwrap()); + let res_string = format!("{}{}", search.command, String::from(bbb.to_str().unwrap())); let res_list = res_string.clone(); return (res_string, res_list); } else if found_bins.len() == 0 { @@ -223,7 +237,8 @@ fn autocomplete_cmd(input: &String) -> (String, String) { } } let first_res = String::from(input); - return(first_res, all_res) + let ret_line = format!("{}{}", &search.command, first_res); + return(ret_line, all_res); } }