Compare commits

..

2 commits

Author SHA1 Message Date
388f709394 fixed () nop because i broke it 2025-05-06 16:19:53 -05:00
a4ac85a0a6 shh 2025-05-06 16:18:30 -05:00
2 changed files with 155 additions and 32 deletions

View file

@ -8,26 +8,108 @@ pub const BUILTINS: [(
&str, &str,
fn(args: Vec<String>, unsplit_args: String, state: &mut super::State) -> i32, fn(args: Vec<String>, unsplit_args: String, state: &mut super::State) -> i32,
&str, &str,
); 19] = [ &str,
("cd", cd, "[dir]"), ); 20] = [
("exit", exit, ""), (
("echo", echo, "[-e] [text ...]"), "cd",
("alias", alias, "[name] [value]"), cd,
("help", help, ""), "[dir]",
("source", eval, "filename [arguments]"), "Change the current directory into the specified one. If unspecified, change the directory into the user's home directory.",
("loadf", loadf, "filename [...]"), ),
("splitf", splitf, "[character] [-e]"), ("exit", exit, "", "Exit the shell."),
("set", set, "name=value [name=value ...]"), (
("dumpvars", dumpvars, ""), "echo",
("unset", unset, "var [var ...]"), echo,
("copyf", copyf, ""), "[-e] [text ...]",
("pastef", pastef, ""), "Output the specified text. If -e is passed, parse escape characters.",
("setf", setf, "var [var ...]"), ),
("getf", getf, "var"), (
("()", nop, ""), "alias",
("if", _if, "condition (statement) [ (else_statement)"), alias,
("while", _while, "condition (statement)"), "name=value [name=value ...]",
("gay", gay, "") "Create one or more command aliases. Command line arguments may be passed to the value.",
),
(
"help",
help,
"[command]",
"Hey, that's me! Get help on a specified builtin or without arguments list all of the available builtin commands.",
),
(
"source",
eval,
"filename [arguments]",
"Evaluate the contents of a file, optionally passing arguments in variables $1 and up.",
),
(
"loadf",
loadf,
"filename [...]",
"Load the contents of a file into the focus.",
),
(
"splitf",
splitf,
"[character] [-e]",
"Split the contents of the focus. If -e is passed, parse escapes.",
),
(
"set",
set,
"name=value [name=value ...]",
"Set one or more variables to values.",
),
("dumpvars", dumpvars, "", "List all variables."),
(
"unset",
unset,
"var [var ...]",
"Unset one or more variables.",
),
(
"copyf",
copyf,
"",
"Copy the contents of the focus to your clipboard.",
),
(
"pastef",
pastef,
"",
"Paste the contents of your clipboard into the focus.",
),
(
"setf",
setf,
"var [var ...]",
"Set one or more variables to the contents of the focus.",
),
(
"getf",
getf,
"var",
"Set the focus to the contents of a variable.",
),
("()", nop, "", "Do nothing and return a status code of 0."),
("nop", nop, "", "Do nothing and return a status code of 0."),
(
"if",
_if,
"condition (statement) [ (else_statement) ]",
"If [condition] returns a status of 0, do (statement). Else, do (else_statement).",
),
(
"while",
_while,
"condition (statement)",
"While [condition] returns a status of 0, do (statement).",
),
(
"gay",
gay,
"",
"Change the colors of the terminal to cycle through the pride flag colors!",
),
]; ];
/// Change the directory /// Change the directory
@ -101,23 +183,61 @@ pub fn alias(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
} }
/// Output help on builtins. /// Output help on builtins.
pub fn help(_: Vec<String>, _: String, _: &mut super::State) -> i32 { pub fn help(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
if args.len() >= 2 {
for builtin in BUILTINS {
if builtin.0 == args[1] {
println!("{} {}: {}", builtin.0, builtin.2, builtin.3);
}
}
return 0;
}
println!( println!(
"sesh, version {} ({})", "{}sesh, version {} ({})",
if state.in_mode {
"\x1b[31;1m"
} else {
""
},
env!("CARGO_PKG_VERSION"), env!("CARGO_PKG_VERSION"),
env!("TARGET") env!("TARGET")
); );
println!("This provides a list of built-in shell commands."); println!("{}This provides a list of built-in shell commands.", if state.in_mode {
println!("Use `man sesh` to find out more about the shell in general."); "\x1b[38;2;255;165;0m"
println!("Use `man -k' or `info' to find out more about commands not in this list."); } else {
""
});
println!("{}Use `man sesh` to find out more about the shell in general.", if state.in_mode {
"\x1b[33;1m"
} else {
""
});
println!("{}Use `man -k' or `info' to find out more about commands not in this list.", if state.in_mode {
"\x1b[32;1m"
} else {
""
});
println!(); println!();
let mut builtins = BUILTINS; let mut builtins = BUILTINS;
builtins.sort_by(|v1, v2| v1.0.cmp(v2.0)); builtins.sort_by(|v1, v2| v1.0.cmp(v2.0));
for builtin in builtins { for (i, builtin) in builtins.iter().enumerate() {
if builtin.0 == "gay" { if builtin.0 == "gay" {
continue; continue;
} }
if state.in_mode {
let table = [
"\x1b[34;1m",
"\x1b[36;1m",
"\x1b[35;1m",
"\x1b[31;1m",
"\x1b[38;2;255;165;0m",
"\x1b[33;1m",
"\x1b[32;1m",
];
let idx = i%table.len();
print!("{}", table[idx]);
}
println!("{} {}", builtin.0, builtin.2); println!("{} {}", builtin.0, builtin.2);
} }
0 0
@ -372,10 +492,7 @@ pub fn _if(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
/// loop while a condition is true /// loop while a condition is true
pub fn _while(args: Vec<String>, _: String, state: &mut super::State) -> i32 { pub fn _while(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
if args.len() < 3 { if args.len() < 3 {
println!( println!("sesh: {0}: usage: {0} condition (statement)", args[0]);
"sesh: {0}: usage: {0} condition (statement)",
args[0]
);
return 1; return 1;
} }
@ -403,4 +520,4 @@ pub fn _while(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
pub fn gay(_: Vec<String>, _: String, state: &mut super::State) -> i32 { pub fn gay(_: Vec<String>, _: String, state: &mut super::State) -> i32 {
state.in_mode = true; state.in_mode = true;
0 0
} }

View file

@ -112,6 +112,7 @@ fn split_statement(statement: &str) -> Vec<String> {
let mut in_str = (false, ' '); let mut in_str = (false, ' ');
let mut escape = false; let mut escape = false;
let mut f = 0usize; let mut f = 0usize;
let mut str_idx = usize::MAX;
for ch in statement.chars() { for ch in statement.chars() {
if ch == '\\' && !in_str.0 { if ch == '\\' && !in_str.0 {
escape = true; escape = true;
@ -121,6 +122,10 @@ fn split_statement(statement: &str) -> Vec<String> {
if ch == ']' { if ch == ']' {
out[i].push(ch); out[i].push(ch);
} }
if ch == ')' && f == str_idx+1 {
out[i].push('(');
out[i].push(ch);
}
escape = false; escape = false;
f += 1; f += 1;
continue; continue;
@ -138,6 +143,7 @@ fn split_statement(statement: &str) -> Vec<String> {
out[i].push(ch); out[i].push(ch);
} }
escape = false; escape = false;
str_idx = f;
f += 1; f += 1;
continue; continue;
} }
@ -387,7 +393,7 @@ fn write_prompt(state: State) -> Result<(), Box<dyn std::error::Error>> {
if state.in_mode { if state.in_mode {
let table = [ let table = [
"\x1b[31;1m", "\x1b[31;1m",
"\x1b[38;2;255;165;0m", "\x1b[38;2;255;165;0;1m",
"\x1b[33;1m", "\x1b[33;1m",
"\x1b[32;1m", "\x1b[32;1m",
"\x1b[34;1m", "\x1b[34;1m",