From 08f80a57c1ff0f586798950eb0d2c41b56006ae8 Mon Sep 17 00:00:00 2001 From: Justine Date: Sun, 19 Feb 2023 19:28:01 +0100 Subject: [PATCH] Aliases work, Alt + . works, README update --- README.md | 32 +++++++------- sqishrc.yaml | 4 +- src/lib.rs | 102 +++++++++++-------------------------------- src/shell/config.rs | 2 - src/shell/history.rs | 16 +++++++ 5 files changed, 59 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index 9749c28..3f9ec97 100644 --- a/README.md +++ b/README.md @@ -2,25 +2,25 @@ Rust Shell. This is an attempt to create a simple shell in Rust, because why not. TO DO: -* Add prompt RGB support -* Implement Alt+z cancels last hotkey, and also "$ENTER_" is like pressing enter -* Add aliases in sqishrc (same old same old) +* Implement Alt+z cancels last hotkey (meh), * rc file shoudl probably just be called .sqishrc, and history .sqishrc.hist -* Add an Ascii header when starting with a waifu or smth I don't know I'm tired -* Re-format syntax, notably for if / else : -```rust -//One-liner should like : -if something() { do_something(); } -//multiline should look like -if something() { - do_it(); -} -else { - do_other(); -} -``` ## sqishrc (Config) See the included sqishrc.yaml.example file included, and copy it as ~/.sqishrc.yaml +## Built-in shortcuts +### As Hotkeys +Some shortcuts are built in. They may be unique to Sqish or be copied from Zsh for example. +* Ctrl+Q : Quits the shell immediatly +* Ctrl+U : Clears currently written line +* Alt+. : Appends the last word from previous command +* Ctrl+A : Jumps to the end of the line +* Ctrl+E : Jumps to the start of the line +* Ctrl+C : Clears the current line and starts a new one + +### In Text: +* !12 : Reruns command number 12 from history (Replace the number with anything) +* !! : Appends the previous command to the current line + + diff --git a/sqishrc.yaml b/sqishrc.yaml index 2be6d6e..1e17ca7 100644 --- a/sqishrc.yaml +++ b/sqishrc.yaml @@ -1,5 +1,5 @@ --- -#This is an example sqishrc. to be copied and modified as ~/.sqish.yaml (not .yml, +#This is an example sqishrc. to be copied and modified as ~/.sqishirc.yaml (not .yml, #I can't be bothered to deal with 2 different extensions). # #Prompt: Defines the promptline. Values are defined in all-caps, between $ and _. @@ -24,7 +24,7 @@ #For example $RGB|108|84|30_ gives you an ugly shade of brown prompt: "$COLORLBLACK_ !$HISTNUMBER_$COLORCYAN_[$USER_@$HOSTNAME_]$RGB|125|0|125_$DIR_> $COLORRESET_" -#Classic aliases +#Classic aliases, can be used in conjunction with hotkeys aliases: gcl: git clone gpl: git pull diff --git a/src/lib.rs b/src/lib.rs index 17e4b4a..39c7332 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -225,19 +225,18 @@ pub mod shell { fn run_cmd(mycommand: &mut String, current_number: &mut i32, - current_pos: &mut usize, - max_pos: &mut usize, conf: &mut SqishConf, stdout: &mut RawTerminal) { - *current_pos = 0; - *max_pos = 0; + //Handling aliases + if conf.aliases.contains_key(mycommand) { + *mycommand = conf.aliases[mycommand].clone(); + } if (mycommand != &String::from("\n")) && (mycommand != &String::from("exit")) { let comm = replace_signs(&mycommand); RawTerminal::suspend_raw_mode(&stdout); let _res = handle_input(&comm); RawTerminal::activate_raw_mode(&stdout); mycommand.clear(); - //Proper printing of return code //for line in res.split('\n') { // if line != "\r" { // write!(stdout, "\r\n{}", line); @@ -278,6 +277,17 @@ pub mod shell { } } + fn append_prev_arg(mycommand: &mut String, current_pos: &mut usize, max_pos: &mut usize) { + let prev_arg = get_prev_arg(); + match prev_arg { + Some(a) => { + for letter in a.chars() { + write_letter(mycommand, current_pos, max_pos, letter); + } + }, + None => (), + }; + } pub fn run_raw() { let stdin = stdin(); @@ -303,8 +313,7 @@ pub mod shell { hotkeys: HashMap::new(), }; let ret_line = format!("Could not build conf, got {}\ - \r\nUsing default promptline:\ - \r\n{}\r\n", e, conf.promptline); + \r\nUsing default promptline", e); write!(stdout, "{}", ret_line); conf }, @@ -337,10 +346,10 @@ pub mod shell { } Key::Char('\n') => { + current_pos = 0; + max_pos = 0; run_cmd(&mut mycommand, &mut current_number, - &mut current_pos, - &mut max_pos, &mut conf, &mut stdout); }, @@ -452,10 +461,6 @@ pub mod shell { write!(stdout, "{}", mycommand); }, - Key::Ctrl('p') => { - print!("{}", current_pos); - } - Key::Ctrl('x') => { clear_line(&max_pos, ¤t_pos); mycommand.clear(); @@ -477,7 +482,6 @@ pub mod shell { } }, - //Pattern matching here ! Key::Alt(x) => { match x { 'a'..='y' => { @@ -491,10 +495,10 @@ pub mod shell { &mut max_pos, c); } else { + current_pos = 0; + max_pos = 0; run_cmd(&mut mycommand, &mut current_number, - &mut current_pos, - &mut max_pos, &mut conf, &mut stdout); } @@ -505,8 +509,12 @@ pub mod shell { 'z' => { print!("Z"); }, + '.' => { + append_prev_arg(&mut mycommand, &mut current_pos, &mut max_pos); + }, + _ => (), - } + }; }, _ => (), @@ -516,64 +524,4 @@ pub mod shell { } } - - - #[cfg(test)] - mod tests { - use super::*; - - fn inittests() { - let filepath = dirs::home_dir().unwrap().join("history.sqish"); - - 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, 2); - } - - #[test] - fn test_gethistfromnumber() { - inittests(); - let mycmd = get_hist_from_number(&1).unwrap(); - 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(); - let towrite = String::from("pwd"); - write_to_history(&towrite); - - //Now check directly against the file - let filepath = dirs::home_dir().unwrap().join("history.sqish"); - 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("3 pwd"); - - assert_eq!(myline.trim(), expected.trim()); - } - } } - - diff --git a/src/shell/config.rs b/src/shell/config.rs index 7f97297..bc850ba 100644 --- a/src/shell/config.rs +++ b/src/shell/config.rs @@ -59,8 +59,6 @@ impl SqishConf { hotkeys: hotkeys, }; - println!("{:?}", out_conf); - out_conf.handle_rgb(); out_conf.handle_colors(); diff --git a/src/shell/history.rs b/src/shell/history.rs index 8e63148..78dd789 100644 --- a/src/shell/history.rs +++ b/src/shell/history.rs @@ -101,3 +101,19 @@ pub fn treat_history_callback(line: &str) -> Option { get_hist_from_number(&mynbr) } +pub fn get_prev_arg() -> Option { + let nbr = get_history_number(); + match nbr { + Ok(r) => { + let prev_cmd = get_hist_from_number(&r).unwrap_or(String::new()); + let last_arg = prev_cmd.split_whitespace().last().unwrap(); + return Some(String::from(last_arg)); + }, + Err(_) => { + return None + }, + }; +} + + +