diff options
Diffstat (limited to 'src/command/history.rs')
-rw-r--r-- | src/command/history.rs | 112 |
1 files changed, 74 insertions, 38 deletions
diff --git a/src/command/history.rs b/src/command/history.rs index a88aeae2..7542496c 100644 --- a/src/command/history.rs +++ b/src/command/history.rs @@ -1,7 +1,10 @@ use std::env; +use std::io::Write; +use std::time::Duration; use eyre::Result; use structopt::StructOpt; +use tabwriter::TabWriter; use atuin_client::database::Database; use atuin_client::history::History; @@ -36,29 +39,65 @@ pub enum Cmd { #[structopt(long, short)] session: bool, - }, - #[structopt( - about="search for a command", - aliases=&["se", "sea", "sear", "searc"], - )] - Search { query: Vec<String> }, + #[structopt(long, short)] + human: bool, + }, #[structopt( about="get the last command ran", aliases=&["la", "las"], )] - Last {}, + Last { + #[structopt(long, short)] + human: bool, + }, } -fn print_list(h: &[History]) { - for i in h { - println!("{}", i.command); +#[allow(clippy::clippy::cast_sign_loss)] +pub fn print_list(h: &[History], human: bool) { + let mut writer = TabWriter::new(std::io::stdout()).padding(2); + + let lines = h.iter().map(|h| { + if human { + let duration = humantime::format_duration(Duration::from_nanos(std::cmp::max( + h.duration, 0, + ) as u64)) + .to_string(); + let duration: Vec<&str> = duration.split(' ').collect(); + let duration = duration[0]; + + format!( + "{}\t{}\t{}\n", + h.timestamp.format("%Y-%m-%d %H:%M:%S"), + h.command.trim(), + duration, + ) + } else { + format!( + "{}\t{}\t{}\n", + h.timestamp.timestamp_nanos(), + h.command.trim(), + h.duration + ) + } + }); + + for i in lines.rev() { + writer + .write_all(i.as_bytes()) + .expect("failed to write to tab writer"); } + + writer.flush().expect("failed to flush tab writer"); } impl Cmd { - pub async fn run(&self, settings: &Settings, db: &mut (impl Database + Send)) -> Result<()> { + pub async fn run( + &self, + settings: &Settings, + db: &mut (impl Database + Send + Sync), + ) -> Result<()> { match self { Self::Start { command: words } => { let command = words.join(" "); @@ -69,7 +108,7 @@ impl Cmd { // print the ID // we use this as the key for calling end println!("{}", h.id); - db.save(&h)?; + db.save(&h).await?; Ok(()) } @@ -78,7 +117,7 @@ impl Cmd { return Ok(()); } - let mut h = db.load(id)?; + let mut h = db.load(id).await?; if h.duration > 0 { debug!("cannot end history - already has duration"); @@ -90,7 +129,7 @@ impl Cmd { h.exit = *exit; h.duration = chrono::Utc::now().timestamp_nanos() - h.timestamp.timestamp_nanos(); - db.update(&h)?; + db.update(&h).await?; if settings.should_sync()? { debug!("running periodic background sync"); @@ -102,41 +141,38 @@ impl Cmd { Ok(()) } - Self::List { session, cwd, .. } => { - const QUERY_SESSION: &str = "select * from history where session = ?;"; - const QUERY_DIR: &str = "select * from history where cwd = ?;"; - const QUERY_SESSION_DIR: &str = - "select * from history where cwd = ?1 and session = ?2;"; - + Self::List { + session, + cwd, + human, + } => { let params = (session, cwd); - let cwd = env::current_dir()?.display().to_string(); let session = env::var("ATUIN_SESSION")?; - let history = match params { - (false, false) => db.list(None, false)?, - (true, false) => db.query(QUERY_SESSION, &[session.as_str()])?, - (false, true) => db.query(QUERY_DIR, &[cwd.as_str()])?, - (true, true) => { - db.query(QUERY_SESSION_DIR, &[cwd.as_str(), session.as_str()])? - } - }; + let query_session = format!("select * from history where session = {};", session); - print_list(&history); + let query_dir = format!("select * from history where cwd = {};", cwd); + let query_session_dir = format!( + "select * from history where cwd = {} and session = {};", + cwd, session + ); - Ok(()) - } + let history = match params { + (false, false) => db.list(None, false).await?, + (true, false) => db.query_history(query_session.as_str()).await?, + (false, true) => db.query_history(query_dir.as_str()).await?, + (true, true) => db.query_history(query_session_dir.as_str()).await?, + }; - Self::Search { query } => { - let history = db.prefix_search(&query.join(""))?; - print_list(&history); + print_list(&history, *human); Ok(()) } - Self::Last {} => { - let last = db.last()?; - print_list(&[last]); + Self::Last { human } => { + let last = db.last().await?; + print_list(&[last], *human); Ok(()) } |