diff --git a/src/lib.rs b/src/lib.rs index 806492d..9e8bf20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,23 +1,24 @@ +#[allow(unused_must_use)] pub mod shell { use std::process::Command; use std::io::stdin; use std::io::stdout; use std::io::Write; - use std::io::ErrorKind; use std::path::Path; use std::env; use std::str; - use std::process::Child; use std::process::Stdio; - use std::fs::File; - use std::fs::OpenOptions; - use std::fs; - use std::io::{self, prelude::*, BufReader}; use users::{get_user_by_uid, get_current_uid}; - use gethostname::gethostname; use termion::event::Key; use termion::input::TermRead; use termion::raw::IntoRawMode; + use termion::color; + + mod history; + use crate::shell::history::*; + + mod autocomplete; + use crate::shell::autocomplete::*; //used for home directory @@ -32,7 +33,7 @@ pub mod shell { while let Some(command) = commands.next() { let mut parts = command.trim().split_whitespace(); - let mut command = parts.next().unwrap(); + let command = parts.next().unwrap(); let args = parts; match command { @@ -45,7 +46,7 @@ pub mod shell { previous_command = None; }, "history" => { - let stdout = Stdio::inherit(); + //let stdout = Stdio::inherit(); let res = get_history(); match res { Ok(r) => return r, @@ -81,9 +82,17 @@ pub mod shell { let output = Command::new(command) .args(args) .stdin(stdin) - .output() - .expect("???"); - &mut resultat.push_str(str::from_utf8(&output.stdout) + .output(); + + let command_result = match output { + Ok(o) => o, + Err(e) => { + eprintln!("\r\nGot error {}", e); + return String::from("!"); + }, + }; + + let _ = &mut resultat.push_str(str::from_utf8(&command_result.stdout) .expect("Could not convert command to str") ); previous_command = None; @@ -94,91 +103,6 @@ pub mod shell { return resultat; } - - fn write_to_history(command: &str) -> Result<(), std::io::Error> { - //Write a command to history - let filepath = dirs::home_dir().unwrap().join("history.sqish"); - let mut file = OpenOptions::new() - .write(true) - .append(true) - .create(true) - .open(&filepath) - .unwrap(); - - let number = match get_history_number() { - Ok(n) => n + 1, - Err(_) => 1 - }; - - writeln!(file, "{} {}", number, command.trim())?; - return Ok(()) - } - - fn get_history_number() -> Result { - //Get the latest number found in history file - let filepath = dirs::home_dir().unwrap().join("history.sqish"); - let file = File::open(filepath)?; - let mut reader = BufReader::new(file).lines(); - let myline = String::from(reader.last().unwrap_or(Ok(String::from("1")))?); - let mut number = myline.split(' ').next().expect("???").parse().unwrap(); - return Ok(number); - } - - fn get_history() -> Result { - let filepath = dirs::home_dir().unwrap().join("history.sqish"); - let file = File::open(filepath)?; - let contents = BufReader::new(file).lines(); - let mut res = String::new(); - for line in contents { - let myline = format!("\r\n{}", line.unwrap()); - res.push_str(&myline); - } - return Ok(res); - } - - 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.sqish"); - - 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 { - let mut mystring = String::from(line); - mystring = mystring.trim().to_string(); - let mut chars = mystring.chars(); - //Skip the ! - chars.next(); - let mynbr: i32 = chars.as_str().parse().unwrap(); - get_hist_from_number(&mynbr) - } - fn build_prompt() -> String { let user = String::from( get_user_by_uid(get_current_uid()) @@ -207,7 +131,10 @@ pub mod shell { .unwrap() ); - let prompt = String::from(format!("[{}@{} in {}] ", user, host, dir_last)); + let prompt = String::from(format!("{}[{}@{} in {}]{} ", + color::Fg(color::LightCyan), + user, host, dir_last, + color::Fg(color::Reset))); return prompt; } @@ -251,13 +178,6 @@ pub mod shell { } } - fn fake_tab(input: &str) -> String { - let faketab = format!(" --This is a fake output for autocomplete from {input}-- "); - //In reality, we would keep the input and append to it - let aaa = String::from(faketab); - return aaa; - } - pub fn run_raw() { let stdin = stdin(); let mut stdout = stdout().into_raw_mode().unwrap(); @@ -272,7 +192,7 @@ pub mod shell { match c.unwrap() { Key::Char('\t') => { - let res = fake_tab(&mycommand); + let res = autocomplete(&mycommand); mycommand.clear(); mycommand.push_str(&res); write!(stdout, "\r\n{}{}", prompt, res); @@ -305,9 +225,9 @@ pub mod shell { break; }, - Key::Char(C) => { - mycommand.push(C); - write!(stdout, "{}", C).unwrap(); + Key::Char(c) => { + mycommand.push(c); + write!(stdout, "{}", c).unwrap(); }, Key::Backspace => { diff --git a/src/shell/autocomplete.rs b/src/shell/autocomplete.rs new file mode 100644 index 0000000..032671a --- /dev/null +++ b/src/shell/autocomplete.rs @@ -0,0 +1,8 @@ +pub fn autocomplete(input: &String) -> String { + let faketab = format!(" --This is a fake output for autocomplete from {input}-- "); + //In reality, we would keep the input and append to it + let aaa = String::from(faketab); + return aaa; +} + + diff --git a/src/shell/history.rs b/src/shell/history.rs new file mode 100644 index 0000000..0f26e45 --- /dev/null +++ b/src/shell/history.rs @@ -0,0 +1,91 @@ +use std::io::Write; +use std::str; +use std::fs::File; +use std::fs::OpenOptions; +use std::io::{prelude::*, BufReader}; + + +pub fn write_to_history(command: &str) -> Result<(), std::io::Error> { + //Write a command to history + let filepath = dirs::home_dir().unwrap().join("history.sqish"); + let mut file = OpenOptions::new() + .write(true) + .append(true) + .create(true) + .open(&filepath) + .unwrap(); + + let number = match get_history_number() { + Ok(n) => n + 1, + Err(_) => 1 + }; + + writeln!(file, "{} {}", number, command.trim())?; + return Ok(()) +} + +pub fn get_history_number() -> Result { + //Get the latest number found in history file + let filepath = dirs::home_dir().unwrap().join("history.sqish"); + let file = File::open(filepath)?; + let reader = BufReader::new(file).lines(); + let myline = String::from(reader.last().unwrap_or(Ok(String::from("1")))?); + let number = myline.split(' ').next().expect("???").parse().unwrap(); + return Ok(number); +} + +pub fn get_history() -> Result { + let filepath = dirs::home_dir().unwrap().join("history.sqish"); + let file = File::open(filepath)?; + let contents = BufReader::new(file).lines(); + let mut res = String::new(); + for line in contents { + let myline = format!("\r\n{}", line.unwrap()); + res.push_str(&myline); + } + return Ok(res); +} + +pub 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.sqish"); + + 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 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; +} + +pub fn treat_history_callback(line: &str) -> Option { + let mut mystring = String::from(line); + mystring = mystring.trim().to_string(); + let mut chars = mystring.chars(); + //Skip the ! + chars.next(); + let mynbr: i32 = chars.as_str().parse().unwrap(); + get_hist_from_number(&mynbr) +} +