diff options
Diffstat (limited to 'src/command')
| -rw-r--r-- | src/command/history.rs | 63 | ||||
| -rw-r--r-- | src/command/import.rs | 107 | ||||
| -rw-r--r-- | src/command/mod.rs | 2 |
3 files changed, 172 insertions, 0 deletions
diff --git a/src/command/history.rs b/src/command/history.rs new file mode 100644 index 00000000..72f821c5 --- /dev/null +++ b/src/command/history.rs @@ -0,0 +1,63 @@ +use std::env; + +use eyre::Result; +use structopt::StructOpt; + +use crate::local::database::{Database, SqliteDatabase}; +use crate::local::history::History; + +#[derive(StructOpt)] +pub enum HistoryCmd { + #[structopt( + about="begins a new command in the history", + aliases=&["s", "st", "sta", "star"], + )] + Start { command: Vec<String> }, + + #[structopt( + about="finishes a new command in the history (adds time, exit code)", + aliases=&["e", "en"], + )] + End { + id: String, + #[structopt(long, short)] + exit: i64, + }, + + #[structopt( + about="list all items in history", + aliases=&["l", "li", "lis"], + )] + List, +} + +impl HistoryCmd { + pub fn run(&self, db: SqliteDatabase) -> Result<()> { + match self { + HistoryCmd::Start { command: words } => { + let command = words.join(" "); + let cwd = env::current_dir()?.display().to_string(); + + let h = History::new(chrono::Utc::now().timestamp_nanos(), command, cwd, -1, -1); + + // print the ID + // we use this as the key for calling end + println!("{}", h.id); + db.save(h)?; + Ok(()) + } + + HistoryCmd::End { id, exit } => { + let mut h = db.load(id)?; + h.exit = *exit; + h.duration = chrono::Utc::now().timestamp_nanos() - h.timestamp; + + db.update(h)?; + + Ok(()) + } + + HistoryCmd::List => db.list(), + } + } +} diff --git a/src/command/import.rs b/src/command/import.rs new file mode 100644 index 00000000..5ece13a8 --- /dev/null +++ b/src/command/import.rs @@ -0,0 +1,107 @@ +use std::env; +use std::path::PathBuf; + +use eyre::{eyre, Result}; +use home::home_dir; +use structopt::StructOpt; + +use crate::local::database::{Database, SqliteDatabase}; +use crate::local::history::History; +use crate::local::import::ImportZsh; +use indicatif::ProgressBar; + +#[derive(StructOpt)] +pub enum ImportCmd { + #[structopt( + about="import history for the current shell", + aliases=&["a", "au", "aut"], + )] + Auto, + + #[structopt( + about="import history from the zsh history file", + aliases=&["z", "zs"], + )] + Zsh, +} + +impl ImportCmd { + fn import_zsh(&self, db: &mut SqliteDatabase) -> Result<()> { + // oh-my-zsh sets HISTFILE=~/.zhistory + // zsh has no default value for this var, but uses ~/.zhistory. + // we could maybe be smarter about this in the future :) + + let histpath = env::var("HISTFILE"); + + let histpath = match histpath { + Ok(p) => PathBuf::from(p), + Err(_) => { + let mut home = home_dir().unwrap(); + home.push(".zhistory"); + + home + } + }; + + if !histpath.exists() { + return Err(eyre!( + "Could not find history file at {}, try setting $HISTFILE", + histpath.to_str().unwrap() + )); + } + + let zsh = ImportZsh::new(histpath.to_str().unwrap())?; + + let progress = ProgressBar::new(zsh.loc); + + let buf_size = 100; + let mut buf = Vec::<History>::with_capacity(buf_size); + + for i in zsh { + match i { + Ok(h) => { + buf.push(h); + } + Err(e) => { + error!("{}", e); + continue; + } + } + + if buf.len() == buf_size { + db.save_bulk(&buf)?; + progress.inc(buf.len() as u64); + + buf = Vec::<History>::with_capacity(buf_size); + } + } + + if buf.len() > 0 { + db.save_bulk(&buf)?; + progress.inc(buf.len() as u64); + } + + progress.finish_with_message("Imported history!"); + + Ok(()) + } + + pub fn run(&self, db: &mut SqliteDatabase) -> Result<()> { + match self { + ImportCmd::Auto => { + let shell = env::var("SHELL").unwrap_or(String::from("NO_SHELL")); + + match shell.as_str() { + "/bin/zsh" => self.import_zsh(db), + + _ => { + println!("cannot import {} history", shell); + Ok(()) + } + } + } + + ImportCmd::Zsh => Ok(()), + } + } +} diff --git a/src/command/mod.rs b/src/command/mod.rs new file mode 100644 index 00000000..c61d2280 --- /dev/null +++ b/src/command/mod.rs @@ -0,0 +1,2 @@ +pub mod history; +pub mod import; |
