Add setf
and getf
and garbage_collect_vars
This commit is contained in:
parent
09c5dfbc5e
commit
04671f7b6a
2 changed files with 63 additions and 2 deletions
|
@ -8,7 +8,7 @@ pub const BUILTINS: [(
|
|||
&str,
|
||||
fn(args: Vec<String>, unsplit_args: String, state: &mut super::State) -> i32,
|
||||
&str,
|
||||
); 13] = [
|
||||
); 15] = [
|
||||
("cd", cd, "[dir]"),
|
||||
("exit", exit, ""),
|
||||
("echo", echo, "[-e] [text ...]"),
|
||||
|
@ -21,7 +21,9 @@ pub const BUILTINS: [(
|
|||
("dumpvars", dumpvars, ""),
|
||||
("unset", unset, "var [var ...]"),
|
||||
("copyf", copyf, ""),
|
||||
("pastef", pastef, "")
|
||||
("pastef", pastef, ""),
|
||||
("setf", setf, "var [var ...]"),
|
||||
("getf", getf, "var"),
|
||||
];
|
||||
|
||||
/// Change the directory
|
||||
|
@ -282,3 +284,40 @@ pub fn pastef(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
|
|||
unsafe { unreachable_unchecked(); }
|
||||
}
|
||||
}
|
||||
|
||||
/// Set a variable to the contents of the focus.
|
||||
pub fn setf(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
|
||||
if args.len() < 2 {
|
||||
println!("sesh: {}: at least one variable required", args[0]);
|
||||
println!("sesh: {0}: usage: {0} var [var ...]", args[0]);
|
||||
return 1;
|
||||
}
|
||||
for var in &args[1..] {
|
||||
state.shell_env.push(super::ShellVar {
|
||||
name: var.to_string(),
|
||||
value: match &state.focus {
|
||||
super::Focus::Str(s) => s.clone(),
|
||||
super::Focus::Vec(_) => format!("{}", state.focus)
|
||||
},
|
||||
});
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// Set the focus to the contents of a variable
|
||||
pub fn getf(args: Vec<String>, _: String, state: &mut super::State) -> i32 {
|
||||
if args.len() != 2 {
|
||||
println!("sesh: {}: exactly one variable required", args[0]);
|
||||
println!("sesh: {0}: usage: {0} var", args[0]);
|
||||
return 1;
|
||||
}
|
||||
let mut val = String::new();
|
||||
for var in &state.shell_env {
|
||||
if var.name == args[1].clone() {
|
||||
val = var.value.clone();
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.focus = super::Focus::Str(val);
|
||||
0
|
||||
}
|
||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -207,6 +207,27 @@ fn substitute_vars(statement: &str, state: State) -> String {
|
|||
out
|
||||
}
|
||||
|
||||
/// remove duplicates, keeping later ones
|
||||
fn garbage_collect_vars(state: &mut State) {
|
||||
state.shell_env.reverse();
|
||||
let mut seen = vec![];
|
||||
let mut remove_indexes = vec![];
|
||||
let mut i = 0usize;
|
||||
for var in &mut state.shell_env {
|
||||
if seen.contains(&var.name) {
|
||||
remove_indexes.push(i);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
seen.push(var.name.clone());
|
||||
i += 1;
|
||||
}
|
||||
for i in remove_indexes {
|
||||
state.shell_env.remove(i);
|
||||
}
|
||||
state.shell_env.sort_by(|v1, v2| v1.name.cmp(&v2.name));
|
||||
}
|
||||
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
/// Evaluate a statement. May include multiple.
|
||||
fn eval(statement: &str, state: &mut State) {
|
||||
|
@ -237,6 +258,7 @@ fn eval(statement: &str, state: &mut State) {
|
|||
let _ = writer.suspend_raw_mode();
|
||||
}
|
||||
let status = builtin.1(statement_split, statement.to_string(), state);
|
||||
garbage_collect_vars(state);
|
||||
if let Some(raw_term) = state.raw_term.clone() {
|
||||
let writer = raw_term.write().unwrap();
|
||||
let _ = writer.activate_raw_mode();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue