From c90c781a32af4304e647231be2a74a444f632a99 Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Sun, 8 Mar 2026 08:39:04 +0100 Subject: history with paths --- src/main.rs | 8 ++++++++ src/run/builtin.rs | 25 ++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src') 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>; } -fn args(args: &[BString], w: &mut dyn Write) -> std::result::Result { +fn read_args(args: &[BString], w: &mut dyn Write) -> std::result::Result { 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, // TODO: temporal control, i.e. before & after @@ -263,13 +265,29 @@ impl Builtin for history { fn io( &self, session: Arc>, - _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(()) } } -- cgit v1.2.3