atuin/src/command/import.rs

114 lines
2.8 KiB
Rust
Raw Normal View History

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
}