summaryrefslogtreecommitdiffstats
path: root/src/state
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-25 15:39:08 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-25 15:39:08 -0500
commita875058500cc93f4d18bd5481d94987232bfbc2a (patch)
tree7ae8781f2f5aac00c7c087481e838967bb47eb07 /src/state
parent000d3619847673cb66c8dd84fce675386f894c75 (diff)
downloadnbsh-a875058500cc93f4d18bd5481d94987232bfbc2a.tar.gz
nbsh-a875058500cc93f4d18bd5481d94987232bfbc2a.zip
rearrange some things
Diffstat (limited to 'src/state')
-rw-r--r--src/state/history/builtins.rs47
-rw-r--r--src/state/history/mod.rs (renamed from src/state/history.rs)6
2 files changed, 51 insertions, 2 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()
+ }
+}
diff --git a/src/state/history.rs b/src/state/history/mod.rs
index f147c37..acdbb44 100644
--- a/src/state/history.rs
+++ b/src/state/history/mod.rs
@@ -4,6 +4,8 @@ use pty_process::Command as _;
use std::error::Error as _;
use std::os::unix::process::ExitStatusExt as _;
+mod builtins;
+
pub struct History {
size: (u16, u16),
entries: Vec<async_std::sync::Arc<async_std::sync::Mutex<Entry>>>,
@@ -602,8 +604,8 @@ async fn run_exe(
resize_r: async_std::channel::Receiver<(u16, u16)>,
event_w: async_std::channel::Sender<crate::event::Event>,
) -> async_std::process::ExitStatus {
- if crate::builtins::is(exe.exe()) {
- let code: i32 = crate::builtins::run(exe.exe(), exe.args()).into();
+ if builtins::is(exe.exe()) {
+ let code: i32 = builtins::run(exe.exe(), exe.args()).into();
return async_std::process::ExitStatus::from_raw(code << 8);
}