diff --git a/src/db.rs b/src/db.rs
index 6b951ba..64d26b1 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -1,5 +1,5 @@
use crate::dir::Dir;
-use crate::types::{Rank, Timestamp};
+use crate::types::{Epoch, Rank};
use crate::util;
use anyhow::{anyhow, bail, Context, Result};
use fs2::FileExt;
@@ -28,21 +28,21 @@ impl DB {
.write(true)
.create(true)
.open(&path_tmp)
- .with_context(|| anyhow!("could not open temporary database"))?;
+ .with_context(|| anyhow!("could not open temporary database file"))?;
file_tmp
.lock_exclusive()
- .with_context(|| anyhow!("could not lock temporary database"))?;
+ .with_context(|| anyhow!("could not lock temporary database file"))?;
let dirs = match File::open(&path) {
Ok(file) => {
- let rd = BufReader::new(&file);
- bincode::deserialize_from(rd)
+ let reader = BufReader::new(&file);
+ bincode::deserialize_from(reader)
.with_context(|| anyhow!("could not deserialize database"))?
}
Err(err) => match err.kind() {
io::ErrorKind::NotFound => Vec::
::new(),
- _ => return Err(err).with_context(|| anyhow!("could not open database")),
+ _ => return Err(err).with_context(|| anyhow!("could not open database file")),
},
};
@@ -59,13 +59,13 @@ impl DB {
if self.modified {
self.file_tmp
.set_len(0)
- .with_context(|| "could not truncate temporary database")?;
+ .with_context(|| "could not truncate temporary database file")?;
- let wr = BufWriter::new(&self.file_tmp);
- bincode::serialize_into(wr, &self.dirs)
+ let writer = BufWriter::new(&self.file_tmp);
+ bincode::serialize_into(writer, &self.dirs)
.with_context(|| anyhow!("could not serialize database"))?;
fs::rename(&self.path_tmp, &self.path)
- .with_context(|| anyhow!("could not move temporary database"))?;
+ .with_context(|| anyhow!("could not move temporary database file"))?;
}
Ok(())
@@ -153,7 +153,7 @@ impl DB {
Ok(())
}
- pub fn add>(&mut self, path: P, now: Timestamp) -> Result<()> {
+ pub fn add>(&mut self, path: P, now: Epoch) -> Result<()> {
let path_abs = path
.as_ref()
.canonicalize()
@@ -165,7 +165,7 @@ impl DB {
match self.dirs.iter_mut().find(|dir| dir.path == path_str) {
None => self.dirs.push(Dir {
- path: path_str.to_owned(),
+ path: path_str.to_string(),
last_accessed: now,
rank: 1.0,
}),
@@ -191,7 +191,7 @@ impl DB {
Ok(())
}
- pub fn query(&mut self, keywords: &[String], now: Timestamp) -> Option {
+ pub fn query(&mut self, keywords: &[String], now: Epoch) -> Option {
loop {
let (idx, dir) = self
.dirs
@@ -209,13 +209,9 @@ impl DB {
}
}
- pub fn query_all(&mut self, mut keywords: Vec) -> Vec {
+ pub fn query_all(&mut self, keywords: &[String]) -> Vec {
self.remove_invalid();
- for keyword in &mut keywords {
- keyword.make_ascii_lowercase();
- }
-
self.dirs
.iter()
.filter(|dir| dir.is_match(&keywords))
@@ -244,6 +240,7 @@ impl DB {
fn remove_invalid(&mut self) {
let orig_len = self.dirs.len();
self.dirs.retain(Dir::is_dir);
+
if orig_len != self.dirs.len() {
self.modified = true;
}
diff --git a/src/dir.rs b/src/dir.rs
index 12664c9..0c62ddb 100644
--- a/src/dir.rs
+++ b/src/dir.rs
@@ -1,4 +1,4 @@
-use crate::types::{Rank, Timestamp};
+use crate::types::{Rank, Epoch};
use serde::{Deserialize, Serialize};
use std::path::Path;
@@ -6,7 +6,7 @@ use std::path::Path;
pub struct Dir {
pub path: String,
pub rank: Rank,
- pub last_accessed: Timestamp,
+ pub last_accessed: Epoch,
}
impl Dir {
@@ -40,10 +40,10 @@ impl Dir {
true
}
- pub fn get_frecency(&self, now: Timestamp) -> Rank {
- const HOUR: Timestamp = 60 * 60;
- const DAY: Timestamp = 24 * HOUR;
- const WEEK: Timestamp = 7 * DAY;
+ pub fn get_frecency(&self, now: Epoch) -> Rank {
+ const HOUR: Epoch = 60 * 60;
+ const DAY: Epoch = 24 * HOUR;
+ const WEEK: Epoch = 7 * DAY;
let duration = now - self.last_accessed;
if duration < HOUR {
diff --git a/src/main.rs b/src/main.rs
index 7a60442..1ef5fcf 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,254 +1,33 @@
mod db;
mod dir;
+mod subcommand;
mod types;
mod util;
-use crate::util::{fzf_helper, get_current_time, get_db};
-use anyhow::{anyhow, Context, Result};
-use clap::arg_enum;
-use std::env;
-use std::path::Path;
+use anyhow::Result;
use structopt::StructOpt;
// TODO: use structopt to parse env variables:
-arg_enum! {
- #[allow(non_camel_case_types)]
- #[derive(Debug)]
- enum Shell {
- bash,
- fish,
- zsh,
- }
-}
-
#[derive(Debug, StructOpt)]
#[structopt(about = "A cd command that learns your habits")]
enum Zoxide {
- #[structopt(about = "Add a new directory or increment its rank")]
- Add { path: Option },
-
- #[structopt(about = "Migrate from z database")]
- Migrate { path: String },
-
- #[structopt(about = "Prints shell configuration")]
- Init {
- #[structopt(possible_values = &Shell::variants(), case_insensitive = true)]
- shell: Shell,
- #[structopt(
- long,
- help = "Prevents zoxide from defining any aliases other than 'z'"
- )]
- no_define_aliases: bool,
- },
-
- #[structopt(about = "Search for a directory")]
- Query {
- keywords: Vec,
- #[structopt(short, long, help = "Opens an interactive selection menu using fzf")]
- interactive: bool,
- },
-
- #[structopt(about = "Remove a directory")]
- Remove { path: String },
-}
-
-fn zoxide_query(mut keywords: Vec) -> Result