2021-02-13 12:37:00 -07:00
|
|
|
use std::env;
|
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
|
|
use eyre::{eyre, Result};
|
|
|
|
use home::home_dir;
|
|
|
|
use structopt::StructOpt;
|
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
use crate::local::database::{Database, Sqlite};
|
2021-02-13 12:37:00 -07:00
|
|
|
use crate::local::history::History;
|
2021-02-14 08:15:26 -07:00
|
|
|
use crate::local::import::Zsh;
|
2021-02-13 12:37:00 -07:00
|
|
|
use indicatif::ProgressBar;
|
|
|
|
|
|
|
|
#[derive(StructOpt)]
|
2021-02-14 08:15:26 -07:00
|
|
|
pub enum Cmd {
|
2021-02-13 12:37:00 -07:00
|
|
|
#[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,
|
|
|
|
}
|
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
impl Cmd {
|
|
|
|
pub fn run(&self, db: &mut Sqlite) -> Result<()> {
|
|
|
|
println!(" A'Tuin ");
|
|
|
|
println!("=====================");
|
|
|
|
println!(" \u{1f30d} ");
|
|
|
|
println!(" \u{1f418}\u{1f418}\u{1f418}\u{1f418} ");
|
|
|
|
println!(" \u{1f422} ");
|
|
|
|
println!("=====================");
|
|
|
|
println!("Importing history...");
|
2021-02-13 12:37:00 -07:00
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
match self {
|
|
|
|
Self::Auto => {
|
|
|
|
let shell = env::var("SHELL").unwrap_or_else(|_| String::from("NO_SHELL"));
|
|
|
|
|
|
|
|
if shell.as_str() == "/bin/zsh" {
|
|
|
|
println!("Detected ZSH");
|
|
|
|
import_zsh(db)
|
|
|
|
} else {
|
|
|
|
println!("cannot import {} history", shell);
|
|
|
|
Ok(())
|
|
|
|
}
|
2021-02-13 12:37:00 -07:00
|
|
|
}
|
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
Self::Zsh => import_zsh(db),
|
2021-02-13 12:37:00 -07:00
|
|
|
}
|
2021-02-14 08:15:26 -07:00
|
|
|
}
|
|
|
|
}
|
2021-02-13 12:37:00 -07:00
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
fn import_zsh(db: &mut Sqlite) -> 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 :)
|
2021-02-13 12:37:00 -07:00
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
let histpath = env::var("HISTFILE");
|
2021-02-13 12:37:00 -07:00
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
let histpath = if let Ok(p) = histpath {
|
|
|
|
PathBuf::from(p)
|
|
|
|
} else {
|
|
|
|
let mut home = home_dir().unwrap();
|
|
|
|
home.push(".zhistory");
|
2021-02-13 12:37:00 -07:00
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
home
|
|
|
|
};
|
|
|
|
|
|
|
|
if !histpath.exists() {
|
|
|
|
return Err(eyre!(
|
|
|
|
"Could not find history file at {}, try setting $HISTFILE",
|
|
|
|
histpath.to_str().unwrap()
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
let zsh = Zsh::new(histpath.to_str().unwrap())?;
|
2021-02-13 12:37:00 -07:00
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
let progress = ProgressBar::new(zsh.loc);
|
2021-02-13 12:37:00 -07:00
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
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;
|
2021-02-13 12:37:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
if buf.len() == buf_size {
|
2021-02-13 12:37:00 -07:00
|
|
|
db.save_bulk(&buf)?;
|
|
|
|
progress.inc(buf.len() as u64);
|
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
buf = Vec::<History>::with_capacity(buf_size);
|
|
|
|
}
|
2021-02-13 12:37:00 -07:00
|
|
|
}
|
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
if !buf.is_empty() {
|
|
|
|
db.save_bulk(&buf)?;
|
|
|
|
progress.inc(buf.len() as u64);
|
|
|
|
}
|
2021-02-13 13:21:49 -07:00
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
progress.finish_with_message("Imported history!");
|
2021-02-13 12:37:00 -07:00
|
|
|
|
2021-02-14 08:15:26 -07:00
|
|
|
Ok(())
|
2021-02-13 12:37:00 -07:00
|
|
|
}
|