diff --git a/src/main.rs b/src/main.rs index 50a9593..17df5ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -121,22 +121,34 @@ fn print_history() -> Result<(), std::io::Error> { fn get_hist_from_number(number: &i32) -> Option { //Returns a command from its number in hist file let filepath = dirs::home_dir().unwrap().join("history.rshell"); - if filepath.exists() { - let file = File::open(filepath).expect("Error opening history file, should NOT happen"); - let mut reader = BufReader::new(file).lines(); - for line in reader { - let current_line = line.expect("Empty history file ? Please rm it"); - let mut s = current_line.split_whitespace(); - let n: i32 = s.next().expect("Error reading a line in hist file").parse().unwrap(); - let c = s.next().expect("No command!"); - if &n == number { - return Some(String::from(c)); - } - } - return None; - } else { + + if filepath.exists() == false { return None; } + + let file = File::open(filepath) + .expect("Error opening history file..."); + + if file.metadata().unwrap().len() < 1 { + return None; + } + + let mut reader = BufReader::new(file).lines(); + + for line in reader { + let current_line = line + .expect("Empty history file ? Please rm it"); + let mut s = current_line.split_whitespace(); + let n: i32 = s.next() + .expect("Error reading a line in hist file") + .parse() + .unwrap(); + let c = s.next().expect("No command!"); + if &n == number { + return Some(String::from(c)); + } + } + return None; } fn treat_history_callback(line: &str) -> Option { @@ -181,30 +193,48 @@ fn build_prompt() -> String { return prompt; } +fn replace_signs(line: String) -> String { + let mut ayo = String::from(&line); + if ayo.contains('~') { + let homedir = dirs::home_dir().unwrap().into_os_string().into_string().unwrap(); + let result = str::replace(&ayo, "~", &homedir); + ayo = String::from(result); + } + + if ayo.contains("!!") { + let prev_comm = get_hist_from_number(&get_history_number().unwrap()).unwrap(); + let result = str::replace(&ayo, "!!", &prev_comm); + ayo = String::from(result); + } + + return ayo; +} fn main(){ loop { print!("{}", build_prompt()); stdout().flush(); - let mut input = String::new(); let bytes = stdin().read_line(&mut input).unwrap(); - if (bytes > 0) && (input != String::from("\n")) { - if input.starts_with("!") { - let command_found = treat_history_callback(&input); - match command_found { - Some(c) => { - write_to_history(&c); - process_line(c); + input = replace_signs(input); + + //history callback + if (bytes > 0) && (input != String::from("\n")) && (input.starts_with('!')) { + let command_found = treat_history_callback(&input); + match command_found { + Some(c) => { + write_to_history(&c); + process_line(c); }, - None => () - }; - } else { - write_to_history(&input); - if process_line(input) { - return - } + None => () + }; + //Regular command + } else if (bytes > 0) && (input != String::from("\n")) { + write_to_history(&input); + if process_line(input) { + return } + //Nothing } else { //Command was empty, new line continue; @@ -220,16 +250,17 @@ mod tests { fn inittests() { let filepath = dirs::home_dir().unwrap().join("history.rshell"); - //if the file exists, new will truncate it + let file = File::create(&filepath).expect("Could not create test history"); writeln!(&file, "1 ls"); + writeln!(&file, "2 pwd"); } #[test] fn test_gethistnumber() { inittests(); let mynumber = get_history_number().unwrap(); - assert_eq!(mynumber, 1); + assert_eq!(mynumber, 2); } #[test] @@ -239,6 +270,20 @@ mod tests { assert_eq!(mycmd, String::from("ls")); } + #[test] + fn test_history_callback() { + inittests(); + let expected = String::from("ls"); + assert_eq!(treat_history_callback("!1"), Some(expected)); + } + + #[test] + fn test_replace_signs() { + inittests(); + let homedir = dirs::home_dir().unwrap().into_os_string().into_string().unwrap(); + assert_eq!(replace_signs(String::from("ls ~ && echo !!")), String::from(format!("ls {} && echo pwd", homedir))); + } + #[test] fn test_writehistline() { inittests(); @@ -250,18 +295,11 @@ mod tests { let file = File::open(filepath).expect("Error"); let mut reader = BufReader::new(file).lines(); let myline = String::from(reader.last().unwrap().expect("Error")); - let expected = String::from("2 pwd"); + let expected = String::from("3 pwd"); assert_eq!(myline.trim(), expected.trim()); } - #[test] - fn test_history_callback() { - inittests(); - let expected = String::from("ls"); - assert_eq!(treat_history_callback("!1"), Some(expected)); - } - }