add many a thing

This commit is contained in:
Arthur Beck 2025-05-06 15:35:53 -05:00
parent 587abe6f9a
commit 8565dd5ca6
3 changed files with 65 additions and 3 deletions

View file

@ -6,6 +6,7 @@ edition = "2024"
[dependencies]
arboard = "3.5.0"
clap = { version = "4.5.37", features = ["derive", "env"] }
ctrlc = "3.4.6"
hostname = "0.4.1"
termion = "4.0.5"
users = "0.11.0"

View file

@ -8,7 +8,7 @@ pub const BUILTINS: [(
&str,
fn(args: Vec<String>, unsplit_args: String, state: &mut super::State) -> i32,
&str,
); 17] = [
); 19] = [
("cd", cd, "[dir]"),
("exit", exit, ""),
("echo", echo, "[-e] [text ...]"),
@ -25,7 +25,9 @@ pub const BUILTINS: [(
("setf", setf, "var [var ...]"),
("getf", getf, "var"),
("()", nop, ""),
("if", _if, "condition ( statement ) [ ( else_statement )"),
("if", _if, "condition (statement) [ (else_statement)"),
("while", _while, "condition (statement)"),
("gay", gay, "")
];
/// Change the directory
@ -113,6 +115,9 @@ pub fn help(_: Vec<String>, _: String, _: &mut super::State) -> i32 {
builtins.sort_by(|v1, v2| v1.0.cmp(v2.0));
for builtin in builtins {
if builtin.0 == "gay" {
continue;
}
println!("{} {}", builtin.0, builtin.2);
}
0
@ -363,3 +368,39 @@ pub fn _if(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
0
}
/// loop while a condition is true
pub fn _while(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
if args.len() < 3 {
println!(
"sesh: {0}: usage: {0} condition (statement)",
args[0]
);
return 1;
}
fn test(condition: String, state: &mut super::State) -> bool {
super::eval(&condition, state);
state.shell_env.reverse();
let mut status = 0i32;
for var in &state.shell_env {
if var.name == "STATUS" {
status = var.value.parse().unwrap();
}
}
state.shell_env.sort_by(|v1, v2| v1.name.cmp(&v2.name));
status == 0
}
while test(args[1].clone(), state) {
super::eval(&args[2].clone(), state);
}
0
}
/// shh
pub fn gay(_: Vec<String>, _: String, state: &mut super::State) -> i32 {
state.in_mode = true;
0
}

View file

@ -96,6 +96,10 @@ struct State {
focus: Focus,
/// Raw terminal.
raw_term: Option<Arc<RwLock<termion::raw::RawTerminal<std::io::Stdout>>>>,
/// sh
in_mode: bool,
/// sh
entries: usize
}
unsafe impl Sync for State {}
@ -318,7 +322,7 @@ fn eval(statement: &str, state: &mut State) {
state.shell_env.push(ShellVar {
name: "STATUS".to_string(),
value: child.wait().unwrap().code().unwrap().to_string(),
value: child.wait().unwrap().code().unwrap_or(255i32).to_string(),
});
if let Some(raw_term) = state.raw_term.clone() {
let writer = raw_term.write().unwrap();
@ -380,6 +384,18 @@ fn write_prompt(state: State) -> Result<(), Box<dyn std::error::Error>> {
.unwrap_or(OsStr::new("?"))
.to_string_lossy(),
);
if state.in_mode {
let table = [
"\x1b[31;1m",
"\x1b[33;1m",
"\x1b[32;1m",
"\x1b[34;1m",
"\x1b[36;1m",
"\x1b[35;1m"
];
let idx = state.entries.saturating_sub(1)%table.len();
prompt += table[idx];
}
print!("{}", prompt);
std::io::stdout().flush()?;
@ -410,6 +426,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.unwrap_or(std::env::home_dir().unwrap_or(PathBuf::from("/"))),
aliases: Vec::new(),
raw_term: None,
in_mode: false,
entries: 0
};
state.shell_env.push(ShellVar {
name: "PROMPT1".to_string(),
@ -434,6 +452,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
value: "true".to_string(),
});
}
let _ = ctrlc::set_handler(|| println!());
let rc = std::fs::read(std::env::home_dir().unwrap().join(".seshrc"));
if rc.is_err() {
@ -608,6 +627,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
history.push(input.clone().trim().to_string());
hist_ptr = history.len();
state.entries += 1;
eval(&input, &mut state);
}
}