From f230e75559c82d056593fe4b0781de5f97caacee Mon Sep 17 00:00:00 2001 From: Ajeet D'Souza <98ajeet@gmail.com> Date: Fri, 18 Sep 2020 01:00:37 +0530 Subject: [PATCH] Avoid removing currently inaccessible directories --- CHANGELOG.md | 3 ++- src/db.rs | 62 ++++++++++++++-------------------------------------- 2 files changed, 19 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9a7944..2b51e5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- `zoxide init` now defines `__zoxide_z*` functions that can be aliased as needed. +- Inaccessible directories are no longer removed; zoxide can now remember paths on removable devices. - `$_ZO_EXCLUDE_DIRS` now supports globs. +- `zoxide init` now defines `__zoxide_z*` functions that can be aliased as needed. ### Changed diff --git a/src/db.rs b/src/db.rs index 7e58d05..ea7cebf 100644 --- a/src/db.rs +++ b/src/db.rs @@ -4,6 +4,7 @@ use float_ord::FloatOrd; use serde::{Deserialize, Serialize}; use uuid::Uuid; +use std::cmp::Reverse; use std::fmt::{self, Display, Formatter}; use std::fs::{self, OpenOptions}; use std::io::{self, Write}; @@ -154,8 +155,22 @@ impl Db { Ok(()) } - pub fn matches<'a>(&'a mut self, now: Epoch, keywords: &[String]) -> DbMatches<'a> { - DbMatches::new(self, now, keywords) + pub fn matches<'a>( + &'a mut self, + now: Epoch, + keywords: &[String], + ) -> impl Iterator { + self.dirs + .sort_unstable_by_key(|dir| Reverse(FloatOrd(dir.get_score(now)))); + + let keywords: Vec = keywords + .iter() + .map(|keyword| keyword.to_lowercase()) + .collect(); + + self.dirs + .iter() + .filter(move |dir| dir.is_match(&keywords) && dir.is_valid()) } fn get_path>(data_dir: P) -> PathBuf { @@ -176,49 +191,6 @@ impl Drop for Db { } } -/// Streaming iterator for matching entries -pub struct DbMatches<'a> { - db: &'a mut Db, - idxs: std::iter::Rev>, - keywords: Vec, -} - -impl<'a> DbMatches<'a> { - pub fn new(db: &'a mut Db, now: Epoch, keywords: &[String]) -> DbMatches<'a> { - db.dirs - .sort_unstable_by_key(|dir| FloatOrd(dir.get_score(now))); - - let idxs = (0..db.dirs.len()).rev(); - let keywords = keywords - .iter() - .map(|keyword| keyword.to_lowercase()) - .collect(); - - DbMatches { db, idxs, keywords } - } - - pub fn next(&mut self) -> Option<&Dir> { - for idx in &mut self.idxs { - let dir = &self.db.dirs[idx]; - - if !dir.is_match(&self.keywords) { - continue; - } - - if !dir.is_valid() { - self.db.dirs.swap_remove(idx); - self.db.modified = true; - continue; - } - - let dir = &self.db.dirs[idx]; - return Some(dir); - } - - None - } -} - pub type Rank = f64; pub type Epoch = i64; // use a signed integer so subtraction can be performed on it