zoxide-remove should accept multiple arguments
This commit is contained in:
parent
18a6052b51
commit
04950b2a58
|
|
@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Added
|
||||
|
||||
- `zoxide add` now accepts multiple arguments.
|
||||
- `zoxide add` and `zoxide remove` now accept multiple arguments.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ _arguments "${_arguments_options[@]}" \
|
|||
'()*--interactive=[]' \
|
||||
'-h[Prints help information]' \
|
||||
'--help[Prints help information]' \
|
||||
'::path:_files -/' \
|
||||
'*::paths:_files -/' \
|
||||
&& ret=0
|
||||
;;
|
||||
esac
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ _zoxide() {
|
|||
return 0
|
||||
;;
|
||||
zoxide__remove)
|
||||
opts=" -i -h --interactive --help <path> "
|
||||
opts=" -i -h --interactive --help <paths>... "
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.SH NAME
|
||||
zoxide-remove - remove a directory from the database
|
||||
.SH SYNOPSIS
|
||||
.B zoxide remove \fIPATH [OPTIONS]\fR
|
||||
.B zoxide remove \fI[PATHS] [OPTIONS]\fR
|
||||
.SH DESCRIPTION
|
||||
If you'd like to permanently exclude a directory from the database, see the
|
||||
\fB_ZO_EXCLUDE_DIRS\fR environment variable in \fBzoxide\fR(1).
|
||||
|
|
|
|||
|
|
@ -126,12 +126,12 @@ pub struct Query {
|
|||
#[derive(Clap, Debug)]
|
||||
pub struct Remove {
|
||||
// Use interactive selection
|
||||
#[clap(conflicts_with = "path", long, short, value_name = "keywords")]
|
||||
#[clap(conflicts_with = "paths", long, short, value_name = "keywords")]
|
||||
pub interactive: Option<Vec<String>>,
|
||||
#[clap(
|
||||
conflicts_with = "interactive",
|
||||
required_unless_present = "interactive",
|
||||
value_hint = ValueHint::DirPath
|
||||
)]
|
||||
pub path: Option<String>,
|
||||
pub paths: Vec<String>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ impl Run for Add {
|
|||
|
||||
if db.modified {
|
||||
db.age(max_age);
|
||||
db.save()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ impl Run for Import {
|
|||
}
|
||||
.context("import error")?;
|
||||
|
||||
Ok(())
|
||||
db.save()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::app::{Query, Run};
|
||||
use crate::config;
|
||||
use crate::db::DatabaseFile;
|
||||
use crate::db::{Database, DatabaseFile};
|
||||
use crate::error::BrokenPipeHandler;
|
||||
use crate::fzf::Fzf;
|
||||
use crate::util;
|
||||
|
|
@ -14,6 +14,12 @@ impl Run for Query {
|
|||
let data_dir = config::data_dir()?;
|
||||
let mut db = DatabaseFile::new(data_dir);
|
||||
let mut db = db.open()?;
|
||||
self.query(&mut db).and(db.save())
|
||||
}
|
||||
}
|
||||
|
||||
impl Query {
|
||||
fn query(&self, db: &mut Database) -> Result<()> {
|
||||
let now = util::current_time()?;
|
||||
|
||||
let mut stream = db.stream(now).with_keywords(&self.keywords);
|
||||
|
|
|
|||
|
|
@ -28,35 +28,25 @@ impl Run for Remove {
|
|||
|
||||
selection = fzf.wait_select()?;
|
||||
let paths = selection.lines().filter_map(|line| line.get(5..));
|
||||
let mut not_found = Vec::new();
|
||||
for path in paths {
|
||||
if !db.remove(&path) {
|
||||
not_found.push(path);
|
||||
bail!("path not found in database: {}", path);
|
||||
}
|
||||
}
|
||||
|
||||
if !not_found.is_empty() {
|
||||
let mut err = "path not found in database:".to_string();
|
||||
for path in not_found {
|
||||
err.push_str("\n ");
|
||||
err.push_str(path.as_ref());
|
||||
}
|
||||
bail!(err);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// unwrap is safe here because path is required_unless_present = "interactive"
|
||||
let path = self.path.as_ref().unwrap();
|
||||
if !db.remove(path) {
|
||||
let path_abs = util::resolve_path(&path)?;
|
||||
let path_abs = util::path_to_str(&path_abs)?;
|
||||
if path_abs != path && !db.remove(path) {
|
||||
bail!("path not found in database:\n {}", &path)
|
||||
for path in self.paths.iter() {
|
||||
if !db.remove(path) {
|
||||
let path_abs = util::resolve_path(&path)?;
|
||||
let path_abs = util::path_to_str(&path_abs)?;
|
||||
if path_abs != path && !db.remove(path_abs) {
|
||||
bail!("path not found in database: {} ({})", path, path_abs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
db.save()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
|
|||
pub struct Database<'file> {
|
||||
pub dirs: DirList<'file>,
|
||||
pub modified: bool,
|
||||
pub data_dir: &'file PathBuf,
|
||||
pub data_dir: &'file Path,
|
||||
}
|
||||
|
||||
impl<'file> Database<'file> {
|
||||
|
|
@ -125,16 +125,6 @@ impl<'file> Database<'file> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for Database<'_> {
|
||||
fn drop(&mut self) {
|
||||
// Since the error can't be properly handled here,
|
||||
// pretty-print it instead.
|
||||
if let Err(e) = self.save() {
|
||||
let _ = writeln!(io::stderr(), "zoxide: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn persist<P: AsRef<Path>>(mut file: NamedTempFile, path: P) -> Result<(), PersistError> {
|
||||
use rand::distributions::{Distribution, Uniform};
|
||||
|
|
@ -231,6 +221,7 @@ mod tests {
|
|||
let mut db = db.open().unwrap();
|
||||
db.add(path, now);
|
||||
db.add(path, now);
|
||||
db.save().unwrap();
|
||||
}
|
||||
{
|
||||
let mut db = DatabaseFile::new(data_dir.path());
|
||||
|
|
@ -253,17 +244,20 @@ mod tests {
|
|||
let mut db = DatabaseFile::new(data_dir.path());
|
||||
let mut db = db.open().unwrap();
|
||||
db.add(path, now);
|
||||
db.save().unwrap();
|
||||
}
|
||||
{
|
||||
let mut db = DatabaseFile::new(data_dir.path());
|
||||
let mut db = db.open().unwrap();
|
||||
assert!(db.remove(path));
|
||||
db.save().unwrap();
|
||||
}
|
||||
{
|
||||
let mut db = DatabaseFile::new(data_dir.path());
|
||||
let mut db = db.open().unwrap();
|
||||
assert!(db.dirs.is_empty());
|
||||
assert!(!db.remove(path));
|
||||
db.save().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue