diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ansi.rs | 2 | ||||
| -rw-r--r-- | src/main.rs | 49 | ||||
| -rw-r--r-- | src/parse/mod.rs | 26 | ||||
| -rw-r--r-- | src/run/mod.rs | 20 |
4 files changed, 84 insertions, 13 deletions
diff --git a/src/ansi.rs b/src/ansi.rs index e04f6d9..522c752 100644 --- a/src/ansi.rs +++ b/src/ansi.rs @@ -130,7 +130,7 @@ pub fn read(debug: bool) -> KeyboardInput { 12 => CtrlL, 18 => CtrlR, 27 => read_escape(debug), - b'\r' => Key(x), + b'\t' | b'\r' => Key(x), x if !x.is_ascii_control() => Key(x), x => todo!("unimplemented control code: {x}"), } diff --git a/src/main.rs b/src/main.rs index 87fcfb4..83796b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,8 +3,8 @@ use std::collections::HashMap; use std::ffi::OsStr; -use std::fs; -use std::io::{self, IsTerminal, Read, Write}; +use std::fs::{self, File}; +use std::io::{self, IsTerminal, Read, Write, stdout}; use std::os::unix::ffi::OsStrExt; use std::os::unix::io::AsRawFd; use std::path::Path; @@ -39,7 +39,7 @@ use crate::completion::{PathCache, completion}; use crate::ctrlc::CtrlC; use crate::cursor::{Direction, move_cursor}; use crate::history::HistoryEntry; -use crate::parse::{Block, ExpString}; +use crate::parse::{Block, ExpString, Parse}; macro_rules! print { ($($x:tt)*) => {{ @@ -90,6 +90,7 @@ pub struct Session { ctrlc: CtrlC, debug_keystrokes: bool, + loud: bool, /// n before end of history.len() /// 0 == not checking history @@ -274,6 +275,37 @@ impl Session { } } +fn exec_rc_file(se: Arc<Mutex<Session>>) { + let rcfile = basedir::config_dir().join(".pishrc"); + let mut rc = Vec::new(); + if !rcfile.exists() { + return; + } + + let mut f = match File::open(&rcfile) { + Ok(f) => f, + Err(e) => { + println!("failed to open {rcfile:?}: {e:?}"); + return; + } + }; + + if let Err(e) = f.read_to_end(&mut rc) { + println!("failed to read {rcfile:?}: {e:?}"); + return; + } + + let script = match parse::Script::parse_from_bytes(&rc) { + Ok(s) => s, + Err(e) => { + println!("failed to parse rc file: {e:?}"); + return; + } + }; + + run::run_script(se, script); +} + fn event_loop() { history::setup(); @@ -300,11 +332,16 @@ fn event_loop() { path_cache: Default::default(), ctrlc: Default::default(), debug_keystrokes: false, + loud: false, }; - print!("{}", se.prompt()); - let session = Arc::new(Mutex::new(se)); + exec_rc_file(session.clone()); + + session.lock().unwrap().loud = true; + + print!("{}", session.lock().unwrap().prompt()); + completion::populate_path_cache(session.clone()); let _sock_dropper = export_fun::listen(session.clone()); @@ -319,7 +356,7 @@ fn event_loop() { Kb::CtrlB => { println!(" Ctrl+B is not yet implemented"); se.reprint_prompt(); - }, + } Kb::CtrlC => { se.clear_prompt(); se.history_visit = 0; diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 88d0362..e061d67 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -49,6 +49,32 @@ pub struct Block { } #[derive(Debug, Clone, PartialEq)] +pub struct Script { + pub stmts: Vec<Ast<PreExpansion>>, +} + +impl Parse for Script { + fn parse(b: &mut Cursor<'_>) -> Result<Self> { + let mut stmts = Vec::new(); + + loop { + b.spaces(); + if b.is_empty() { + break; + } + + match Ast::parse(b) { + Ok(s) => stmts.push(s), + Err(ParseError::Eof) => break, + Err(e) => Err(e)?, + } + } + + Ok(Script { stmts }) + } +} + +#[derive(Debug, Clone, PartialEq)] pub enum Ast<T: Stage> { FunDecl(FunDecl<T>), VarAssign(VarAssign<T>), diff --git a/src/run/mod.rs b/src/run/mod.rs index 6fe0d45..8a728c5 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -482,13 +482,21 @@ pub fn run(se: Arc<Mutex<Session>>, parsed: Ast<PreExpansion>) { let result = exec(se.clone(), parsed); se.lock().unwrap().raw.enable(); - let status_string = match result { - Ok(_) => String::new(), - Err(e) => format!("{}\r\n", e.error_message()), - }; + if se.lock().unwrap().loud { + let status_string = match result { + Ok(_) => String::new(), + Err(e) => format!("{}\r\n", e.error_message()), + }; + + print!("\r{status_string}{}", se.lock().unwrap().prompt()); + let _ = std::io::stdout().lock().flush(); + } +} - print!("\r{status_string}{}", se.lock().unwrap().prompt()); - let _ = std::io::stdout().lock().flush(); +pub fn run_script(se: Arc<Mutex<Session>>, script: crate::parse::Script) { + for stmt in script.stmts { + run(se.clone(), stmt); + } } #[derive(Debug)] |
