Add array length syntax ${arr[#]}
Map read path now expands variables before splitting on ., fixing map "$node" with dotted paths
Map assignment path uses quote-aware token splitting, enabling quoted keys like "--type="
Completion errors now display above prompt instead of being overwritten
Fix nested if/fi parser bug when closing keywords appear on separate lines
Add QuoteState enum, replacing ad-hoc quote tracking booleans across lexer, highlighter, and expansion
Add split_tk_at/split_tk for quote-aware token splitting with span preservation
Refactor setup_builtin to accept optional argv for deferred expansion
Add ariadne dependency (not yet wired up)
65 lines
1.3 KiB
Rust
65 lines
1.3 KiB
Rust
use crate::{
|
|
jobs::JobBldr,
|
|
libsh::error::{ShErr, ShErrKind, ShResult},
|
|
parse::{NdRule, Node},
|
|
prelude::*,
|
|
state::{self},
|
|
};
|
|
|
|
use super::setup_builtin;
|
|
|
|
pub fn cd(node: Node, job: &mut JobBldr) -> ShResult<()> {
|
|
let span = node.get_span();
|
|
let NdRule::Command {
|
|
assignments: _,
|
|
argv,
|
|
} = node.class
|
|
else {
|
|
unreachable!()
|
|
};
|
|
|
|
let (argv, _) = setup_builtin(Some(argv), job, None)?;
|
|
let argv = argv.unwrap();
|
|
|
|
let new_dir = if let Some((arg, _)) = argv.into_iter().next() {
|
|
PathBuf::from(arg)
|
|
} else {
|
|
PathBuf::from(env::var("HOME").unwrap())
|
|
};
|
|
|
|
if !new_dir.exists() {
|
|
return Err(ShErr::full(
|
|
ShErrKind::ExecFail,
|
|
format!("cd: No such file or directory '{}'", new_dir.display()),
|
|
span,
|
|
));
|
|
}
|
|
|
|
if !new_dir.is_dir() {
|
|
return Err(ShErr::full(
|
|
ShErrKind::ExecFail,
|
|
format!("cd: Not a directory '{}'", new_dir.display()),
|
|
span,
|
|
));
|
|
}
|
|
|
|
if let Err(e) = env::set_current_dir(new_dir) {
|
|
return Err(ShErr::full(
|
|
ShErrKind::ExecFail,
|
|
format!("cd: Failed to change directory: {}", e),
|
|
span,
|
|
));
|
|
}
|
|
let new_dir = env::current_dir().map_err(|e| {
|
|
ShErr::full(
|
|
ShErrKind::ExecFail,
|
|
format!("cd: Failed to get current directory: {}", e),
|
|
span,
|
|
)
|
|
})?;
|
|
unsafe { env::set_var("PWD", new_dir) };
|
|
|
|
state::set_status(0);
|
|
Ok(())
|
|
}
|