aboutsummaryrefslogtreecommitdiffstats
path: root/src/command/import.rs
diff options
context:
space:
mode:
authorEllie Huxtable <e@elm.sh>2021-02-13 19:37:00 +0000
committerEllie Huxtable <e@elm.sh>2021-02-13 19:37:31 +0000
commit099afe66ecfb569a8a04b66425ded29665e6a37c (patch)
tree7bb1baadb9304fa0d4f353d0849f962e2af209e3 /src/command/import.rs
parentRecord command exit code and duration (diff)
downloadatuin-099afe66ecfb569a8a04b66425ded29665e6a37c.zip
Implement history import
Diffstat (limited to '')
-rw-r--r--src/command/import.rs107
1 files changed, 107 insertions, 0 deletions
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(()),
+ }
+ }
+}