aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ansi.rs2
-rw-r--r--src/main.rs49
-rw-r--r--src/parse/mod.rs26
-rw-r--r--src/run/mod.rs20
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)]