summaryrefslogtreecommitdiffstats
path: root/src/state/history/builtins.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/history/builtins.rs')
-rw-r--r--src/state/history/builtins.rs47
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()
+ }
+}