aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/run/builtin.rs50
-rw-r--r--src/run/mod.rs51
2 files changed, 61 insertions, 40 deletions
diff --git a/src/run/builtin.rs b/src/run/builtin.rs
index e69de29..feba7f9 100644
--- a/src/run/builtin.rs
+++ b/src/run/builtin.rs
@@ -0,0 +1,50 @@
+use super::Builtin;
+use crate::*;
+
+pub struct Cd;
+impl Builtin for Cd {
+ fn name(&self) -> &str {
+ "cd"
+ }
+ fn mod_session(&self, _: &mut Session, args: &[BString]) {
+ let target: &Path = match args.get(0).map(|v| &v[..]) {
+ Some(b"-") => todo!("prev"),
+ Some(path) => OsStr::from_bytes(path).as_ref(),
+ None => todo!("homedir"),
+ };
+
+ // TODO: let mod_session builtins return nonzero exit code
+ let _ = std::env::set_current_dir(target);
+ }
+}
+
+pub struct Clear;
+impl Builtin for Clear {
+ fn name(&self) -> &str {
+ "clear"
+ }
+ fn mod_session(&self, _: &mut Session, _: &[BString]) {
+ print!("\x1B[2J\x1B[1;1H");
+ }
+}
+
+/// restart shell
+pub struct Re;
+impl Builtin for Re {
+ fn name(&self) -> &str {
+ "re"
+ }
+
+ fn mod_session(&self, session: &mut Session, _args: &[BString]) {
+ session.raw.disable();
+ let _ = Command::new("cargo").arg("run").status();
+ session.raw.disable();
+ std::process::exit(0);
+ }
+}
+
+
+// TODO
+// from" => todo!("read from file"),
+// to" | b"into" => todo!("write into file"),
+// append" => todo!("append to file"),
diff --git a/src/run/mod.rs b/src/run/mod.rs
index 82409e9..0a51da2 100644
--- a/src/run/mod.rs
+++ b/src/run/mod.rs
@@ -6,15 +6,17 @@ use std::path::PathBuf;
use crate::parse::Ast;
use crate::*;
+mod builtin;
+
pub fn run(se: &Session, cmd: Vec<u8>) {
run_command(&se.raw, cmd);
}
-pub trait Builtin : Send + Sync {
- fn name(&self) -> & str;
+pub trait Builtin: Send + Sync {
+ fn name(&self) -> &str;
/// quick synchronous call, `cd` for example
- fn mod_session(&self, session: &mut Session) {}
+ fn mod_session(&self, session: &mut Session, args: &[BString]) {}
/// potentially long, pipelineable thread, builtin `cat` for example
fn io(
@@ -27,7 +29,12 @@ pub trait Builtin : Send + Sync {
}
}
-const BUILTINS: &[&'static dyn Builtin] = &[];
+const BUILTINS: &[&'static dyn Builtin] = &[
+ &builtin::Cd,
+ &builtin::Clear,
+ #[cfg(debug_assertions)]
+ &builtin::Re,
+];
pub struct CommandDispatch {
map: HashMap<BString, CommandKind>,
@@ -110,42 +117,6 @@ fn run_command(raw: &ScopedRawMode, line: Vec<u8>) {
todo!("can only handle pipes");
};
- // simple command that can probably be builtin
- // TODO: handle builtins uniformly instead of big if case
- if pipes.cmds.len() == 1 {
- let c = &pipes.cmds[0];
- match &c.cmd[..] {
- b"cd" => {
- let target: &Path = match c.args.get(0).map(|v| &v[..]) {
- Some(b"-") => todo!("prev"),
- Some(path) => OsStr::from_bytes(path).as_ref(),
- None => todo!("homedir"),
- };
-
- if let Err(_) = std::env::set_current_dir(target) {
- print!("ERR {PROMPT}");
- } else {
- print!("{PROMPT}");
- }
-
- return;
- }
- b"clear" => clear_screen(),
- #[cfg(debug_assertions)]
- b"re" => {
- // restart shell
- raw.disable();
- let _ = Command::new("cargo").arg("run").status();
- raw.disable();
- std::process::exit(0);
- }
- b"from" => todo!("read from file"),
- b"to" | b"into" => todo!("write into file"),
- b"append" => todo!("append to file"),
- _ => (),
- }
- }
-
let mut children: Vec<Child> = Vec::new();
let mut prev_stdout = None;
let mut spawn_error = false;