diff options
Diffstat (limited to 'src/state/history/builtins.rs')
-rw-r--r-- | src/state/history/builtins.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/state/history/builtins.rs b/src/state/history/builtins.rs new file mode 100644 index 0000000..e8f87da --- /dev/null +++ b/src/state/history/builtins.rs @@ -0,0 +1,47 @@ +pub fn is(exe: &str) -> bool { + matches!(exe, "cd") +} + +pub fn run<'a>(exe: &str, args: impl IntoIterator<Item = &'a str>) -> u8 { + match exe { + "cd" => impls::cd( + args.into_iter() + .map(std::convert::AsRef::as_ref) + .next() + .unwrap_or(""), + ), + _ => unreachable!(), + } +} + +mod impls { + pub fn cd(dir: &str) -> u8 { + let dir = if dir.is_empty() { + home() + } else if dir.starts_with('~') { + let path: std::path::PathBuf = dir.into(); + if let std::path::Component::Normal(prefix) = + path.components().next().unwrap() + { + if prefix.to_str() == Some("~") { + home().join(path.strip_prefix(prefix).unwrap()) + } else { + // TODO + return 1; + } + } else { + unreachable!() + } + } else { + dir.into() + }; + match std::env::set_current_dir(dir) { + Ok(()) => 0, + Err(_) => 1, + } + } + + fn home() -> std::path::PathBuf { + std::env::var_os("HOME").unwrap().into() + } +} |