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::::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::::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<()> { println!(" A'Tuin "); println!("====================="); println!(" 🌍 "); println!(" 🐘🐘🐘🐘 "); println!(" 🐢 "); println!("====================="); println!("Importing history..."); match self { ImportCmd::Auto => { let shell = env::var("SHELL").unwrap_or(String::from("NO_SHELL")); match shell.as_str() { "/bin/zsh" => { println!("Detected ZSH"); self.import_zsh(db) } _ => { println!("cannot import {} history", shell); Ok(()) } } } ImportCmd::Zsh => self.import_zsh(db), } } }