diff options
| author | Jonas Maier <> | 2026-03-08 08:39:04 +0100 |
|---|---|---|
| committer | Jonas Maier <> | 2026-03-08 08:39:04 +0100 |
| commit | c90c781a32af4304e647231be2a74a444f632a99 (patch) | |
| tree | 3a3b1d293986af03d0fc2d7878b0b27a0521fc4e | |
| parent | deafab9c930ab092c4ee8abd4cbe09c7eb34aa22 (diff) | |
| download | pish-c90c781a32af4304e647231be2a74a444f632a99.tar.gz | |
history with paths
| -rw-r--r-- | pish_derive/src/lib.rs | 2 | ||||
| -rw-r--r-- | src/main.rs | 8 | ||||
| -rw-r--r-- | src/run/builtin.rs | 25 |
3 files changed, 31 insertions, 4 deletions
diff --git a/pish_derive/src/lib.rs b/pish_derive/src/lib.rs index 2ac98f7..0d06aa5 100644 --- a/pish_derive/src/lib.rs +++ b/pish_derive/src/lib.rs @@ -76,7 +76,7 @@ pub fn derive_cli(input: TokenStream) -> TokenStream { let expanded = quote! { impl ArgParse for #name { fn parse<'a>(args: &'a [BString]) -> std::result::Result<Self, ArgParseError<'a>> { - let mut iter = args.iter().skip(1); + let mut iter = args.iter(); #(#field_parsers_init)* diff --git a/src/main.rs b/src/main.rs index 9a4e692..3687cd0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::env::current_dir; use std::ffi::OsStr; use std::fs; use std::io::{self, IsTerminal, Read, Write}; @@ -60,7 +61,13 @@ type bstr = [u8]; #[derive(Clone)] struct HistoryEntry { + /// time of execution pub time: date::DateTime, + + /// absolute path where the command was executed + pub loc: BString, + + /// the command pub cmd: BString, } @@ -68,6 +75,7 @@ impl HistoryEntry { pub fn new(cmd: BString) -> Self { Self { time: date::DateTime::now(), + loc: current_dir().unwrap().as_os_str().as_encoded_bytes().to_vec(), cmd, } } diff --git a/src/run/builtin.rs b/src/run/builtin.rs index 366aaa5..c3153d6 100644 --- a/src/run/builtin.rs +++ b/src/run/builtin.rs @@ -20,7 +20,7 @@ pub trait ArgParse: Sized { fn parse<'a>(args: &'a [BString]) -> std::result::Result<Self, ArgParseError<'a>>; } -fn args<T: ArgParse>(args: &[BString], w: &mut dyn Write) -> std::result::Result<T, Error> { +fn read_args<T: ArgParse>(args: &[BString], w: &mut dyn Write) -> std::result::Result<T, Error> { let err = match T::parse(args) { Ok(t) => return Ok(t), Err(e) => e, @@ -245,10 +245,12 @@ impl Builtin for builtins { } } -#[derive(FromArgs)] +#[derive(FromArgs, Debug)] struct HistoryArgs { + /// displays only local shell session history local: bool, + /// displays only history of current directory here: bool, at: Option<PathBuf>, // TODO: temporal control, i.e. before & after @@ -263,13 +265,29 @@ impl Builtin for history { fn io( &self, session: Arc<Mutex<Session>>, - _args: &[BString], + args: &[BString], _stdin: &mut dyn Read, stdout: &mut dyn Write, ) -> Result { + let args: HistoryArgs = read_args(args, stdout)?; let hist = session.lock().unwrap().history.clone(); let now = crate::date::DateTime::now(); + + let in_dir = if args.here { + current_dir()?.as_os_str().as_bytes().to_vec() + } else if let Some(path) = args.at { + path.as_os_str().as_bytes().to_vec() + } else { + Vec::new() + }; + + // TODO: local handling (first implement global history) + for entry in hist { + if !entry.loc.starts_with(&in_dir) { + continue; + } + let delta = now.relative_to(&entry.time); for _ in 0..crate::date::DateTime::longest_reasonable_delta() - delta.len() { stdout.write_all(b" ")?; @@ -279,6 +297,7 @@ impl Builtin for history { stdout.write_all(&entry.cmd)?; stdout.write_all(b"\n")?; } + Ok(()) } } |
