aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pish_derive/src/lib.rs2
-rw-r--r--src/main.rs8
-rw-r--r--src/run/builtin.rs25
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(())
}
}