Avoid removing currently inaccessible directories

This commit is contained in:
Ajeet D'Souza 2020-09-18 01:00:37 +05:30
parent 5cfcd79c39
commit f230e75559
2 changed files with 19 additions and 46 deletions

View File

@ -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

View File

@ -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<Item = &'a Dir> {
self.dirs
.sort_unstable_by_key(|dir| Reverse(FloatOrd(dir.get_score(now))));
let keywords: Vec<String> = keywords
.iter()
.map(|keyword| keyword.to_lowercase())
.collect();
self.dirs
.iter()
.filter(move |dir| dir.is_match(&keywords) && dir.is_valid())
}
fn get_path<P: AsRef<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<std::ops::Range<usize>>,
keywords: Vec<String>,
}
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