cd function

Signed-off-by: Ava Hahn <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2023-04-17 22:11:49 -07:00
parent db55c54dd3
commit ee1ef9700d
Signed by: affine
GPG key ID: 3A4645B8CF806069
6 changed files with 87 additions and 33 deletions

View file

@ -218,7 +218,8 @@ fn tok_is_symbol(token: &str) -> Option<String> {
t != '?' &&
t != '=' &&
t != '.' &&
t != '/'
t != '/' &&
t != '.'
{
return None;
}

View file

@ -26,7 +26,7 @@ use std::env::{vars, var, current_dir};
use std::rc::Rc;
fn l_prompt_default_callback(_: &Seg, _: &mut SymTable) -> Result<Ctr, String> {
Ok(Ctr::String("λ".to_string()))
Ok(Ctr::String(">".to_string()))
}
fn r_prompt_default_callback(_: &Seg, _: &mut SymTable) -> Result<Ctr, String> {
@ -34,7 +34,7 @@ fn r_prompt_default_callback(_: &Seg, _: &mut SymTable) -> Result<Ctr, String> {
}
fn prompt_delimiter_default_callback(_: &Seg, _: &mut SymTable) -> Result<Ctr, String> {
Ok(Ctr::String(">".to_string()))
Ok(Ctr::String("λ ".to_string()))
}
fn get_paths() -> Vec<String> {

View file

@ -648,6 +648,17 @@ pub fn dynamic_stdlib(syms: &mut SymTable, shell: Option<Rc<RefCell<posix::Shell
if posix_cfg_user_form {
posix::load_posix_shell(syms, shell_state);
syms.insert(
"cd".to_string(),
Symbol {
name: String::from("cd"),
args: Args::Strict(vec![Type::String]),
conditional_branches: false,
docs: posix::CD_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(posix::cd_callback)),
..Default::default()
},
);
}
}

View file

@ -15,18 +15,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::segment::{Ctr, Seg};
use crate::sym::{SymTable, ValueType, Symbol, Args};
use crate::eval::eval;
use crate::run;
use std::collections::VecDeque;
use std::cell::RefCell;
use std::rc::Rc;
use std::fs::File;
use std::process::{Command, Child, Stdio};
use nix::unistd;
use ctrlc;
use std::fs::OpenOptions;
use {
crate::{
segment::{Ctr, Seg},
sym::{
SymTable, ValueType,
Symbol, Args,
},
eval::eval,
run,
},
std::{
collections::VecDeque,
cell::RefCell,
rc::Rc,
fs::{File, OpenOptions},
path::Path,
process::{
Command, Child,
Stdio,
},
env::set_current_dir,
},
nix::unistd,
ctrlc,
};
pub struct ShellState {
pub parent_pid: unistd::Pid,
@ -54,7 +69,8 @@ pub fn args_from_ast(ast: &Seg, syms: &mut SymTable) -> Vec<String> {
_ => args.push(res_ctr.to_string()) == (),
}
} else {
eprintln!("couldnt eval args!") != ()
eprintln!("couldnt eval args: {}",
eval_res.err().unwrap()) != ()
}
},
Ctr::Seg(ref form) => {
@ -67,7 +83,8 @@ pub fn args_from_ast(ast: &Seg, syms: &mut SymTable) -> Vec<String> {
_ => args.push(res_ctr.to_string()) == (),
}
} else {
eprintln!("couldnt eval args!") != ()
eprintln!("couldnt eval args: {}",
eval_res.err().unwrap()) != ()
}
},
Ctr::Lambda(_) => eprintln!("lambda passed as shell parameter") != (),
@ -443,6 +460,21 @@ fn bg_callback(_ast: &Seg, _syms: &mut SymTable, _state: &mut ShellState) -> Res
unimplemented!()
}
pub const CD_DOCSTRING: &str =
"Expects 1 argument (a string). Changes to a new directory";
pub fn cd_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
if let Ctr::String(ref dir) = *ast.car {
let dirp = Path::new(dir);
if let Err(s) = set_current_dir(&dirp) {
Err(format!("{}", s))
} else {
Ok(Ctr::None)
}
} else {
Err(format!("impossible err: arg not a string"))
}
}
pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>>) {
let pid = unistd::getpid();
let pgid_res = unistd::getpgid(Some(pid));