feat: --basedir query option
This commit is contained in:
parent
30129f4344
commit
6866c85e0a
|
@ -120,6 +120,7 @@ _arguments "${_arguments_options[@]}" : \
|
||||||
(query)
|
(query)
|
||||||
_arguments "${_arguments_options[@]}" : \
|
_arguments "${_arguments_options[@]}" : \
|
||||||
'--exclude=[Exclude the current directory]:path:_files -/' \
|
'--exclude=[Exclude the current directory]:path:_files -/' \
|
||||||
|
'(--exclude)--basedir=[Only search within this directory]:path:_files -/' \
|
||||||
'-a[Show unavailable directories]' \
|
'-a[Show unavailable directories]' \
|
||||||
'--all[Show unavailable directories]' \
|
'--all[Show unavailable directories]' \
|
||||||
'(-l --list)-i[Use interactive selection]' \
|
'(-l --list)-i[Use interactive selection]' \
|
||||||
|
|
|
@ -102,6 +102,7 @@ Register-ArgumentCompleter -Native -CommandName 'zoxide' -ScriptBlock {
|
||||||
}
|
}
|
||||||
'zoxide;query' {
|
'zoxide;query' {
|
||||||
[CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Exclude the current directory')
|
[CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Exclude the current directory')
|
||||||
|
[CompletionResult]::new('--basedir', '--basedir', [CompletionResultType]::ParameterName, 'Only search within this directory')
|
||||||
[CompletionResult]::new('-a', '-a', [CompletionResultType]::ParameterName, 'Show unavailable directories')
|
[CompletionResult]::new('-a', '-a', [CompletionResultType]::ParameterName, 'Show unavailable directories')
|
||||||
[CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'Show unavailable directories')
|
[CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'Show unavailable directories')
|
||||||
[CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Use interactive selection')
|
[CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Use interactive selection')
|
||||||
|
|
|
@ -199,7 +199,7 @@ _zoxide() {
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
zoxide__query)
|
zoxide__query)
|
||||||
opts="-a -i -l -s -h -V --all --interactive --list --score --exclude --help --version [KEYWORDS]..."
|
opts="-a -i -l -s -h -V --all --interactive --list --score --exclude --basedir --help --version [KEYWORDS]..."
|
||||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||||
return 0
|
return 0
|
||||||
|
@ -212,6 +212,13 @@ _zoxide() {
|
||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
--basedir)
|
||||||
|
COMPREPLY=()
|
||||||
|
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
|
||||||
|
compopt -o plusdirs
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -90,6 +90,7 @@ set edit:completion:arg-completer[zoxide] = {|@words|
|
||||||
}
|
}
|
||||||
&'zoxide;query'= {
|
&'zoxide;query'= {
|
||||||
cand --exclude 'Exclude the current directory'
|
cand --exclude 'Exclude the current directory'
|
||||||
|
cand --basedir 'Only search within this directory'
|
||||||
cand -a 'Show unavailable directories'
|
cand -a 'Show unavailable directories'
|
||||||
cand --all 'Show unavailable directories'
|
cand --all 'Show unavailable directories'
|
||||||
cand -i 'Use interactive selection'
|
cand -i 'Use interactive selection'
|
||||||
|
|
|
@ -62,6 +62,7 @@ complete -c zoxide -n "__fish_zoxide_using_subcommand init" -l no-cmd -d 'Preven
|
||||||
complete -c zoxide -n "__fish_zoxide_using_subcommand init" -s h -l help -d 'Print help'
|
complete -c zoxide -n "__fish_zoxide_using_subcommand init" -s h -l help -d 'Print help'
|
||||||
complete -c zoxide -n "__fish_zoxide_using_subcommand init" -s V -l version -d 'Print version'
|
complete -c zoxide -n "__fish_zoxide_using_subcommand init" -s V -l version -d 'Print version'
|
||||||
complete -c zoxide -n "__fish_zoxide_using_subcommand query" -l exclude -d 'Exclude the current directory' -r -f -a "(__fish_complete_directories)"
|
complete -c zoxide -n "__fish_zoxide_using_subcommand query" -l exclude -d 'Exclude the current directory' -r -f -a "(__fish_complete_directories)"
|
||||||
|
complete -c zoxide -n "__fish_zoxide_using_subcommand query" -l basedir -d 'Only search within this directory' -r -f -a "(__fish_complete_directories)"
|
||||||
complete -c zoxide -n "__fish_zoxide_using_subcommand query" -s a -l all -d 'Show unavailable directories'
|
complete -c zoxide -n "__fish_zoxide_using_subcommand query" -s a -l all -d 'Show unavailable directories'
|
||||||
complete -c zoxide -n "__fish_zoxide_using_subcommand query" -s i -l interactive -d 'Use interactive selection'
|
complete -c zoxide -n "__fish_zoxide_using_subcommand query" -s i -l interactive -d 'Use interactive selection'
|
||||||
complete -c zoxide -n "__fish_zoxide_using_subcommand query" -s l -l list -d 'List all matching directories'
|
complete -c zoxide -n "__fish_zoxide_using_subcommand query" -s l -l list -d 'List all matching directories'
|
||||||
|
|
|
@ -214,6 +214,19 @@ const completion: Fig.Spec = {
|
||||||
template: "folders",
|
template: "folders",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "--basedir",
|
||||||
|
description: "Only search within this directory",
|
||||||
|
exclusiveOn: [
|
||||||
|
"--exclude",
|
||||||
|
],
|
||||||
|
isRepeatable: true,
|
||||||
|
args: {
|
||||||
|
name: "basedir",
|
||||||
|
isOptional: true,
|
||||||
|
template: "folders",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: ["-a", "--all"],
|
name: ["-a", "--all"],
|
||||||
description: "Show unavailable directories",
|
description: "Show unavailable directories",
|
||||||
|
|
|
@ -186,6 +186,10 @@ pub struct Query {
|
||||||
/// Exclude the current directory
|
/// Exclude the current directory
|
||||||
#[clap(long, value_hint = ValueHint::DirPath, value_name = "path")]
|
#[clap(long, value_hint = ValueHint::DirPath, value_name = "path")]
|
||||||
pub exclude: Option<String>,
|
pub exclude: Option<String>,
|
||||||
|
|
||||||
|
/// Only search within this directory
|
||||||
|
#[clap(long, value_hint = ValueHint::DirPath, value_name = "path", conflicts_with = "exclude")]
|
||||||
|
pub basedir: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove a directory from the database
|
/// Remove a directory from the database
|
||||||
|
|
|
@ -79,7 +79,8 @@ impl Query {
|
||||||
fn get_stream<'a>(&self, db: &'a mut Database, now: Epoch) -> Result<Stream<'a>> {
|
fn get_stream<'a>(&self, db: &'a mut Database, now: Epoch) -> Result<Stream<'a>> {
|
||||||
let mut options = StreamOptions::new(now)
|
let mut options = StreamOptions::new(now)
|
||||||
.with_keywords(self.keywords.iter().map(|s| s.as_str()))
|
.with_keywords(self.keywords.iter().map(|s| s.as_str()))
|
||||||
.with_exclude(config::exclude_dirs()?);
|
.with_exclude(config::exclude_dirs()?)
|
||||||
|
.with_basedir(self.basedir.clone());
|
||||||
if !self.all {
|
if !self.all {
|
||||||
let resolve_symlinks = config::resolve_symlinks();
|
let resolve_symlinks = config::resolve_symlinks();
|
||||||
options = options.with_exists(true).with_resolve_symlinks(resolve_symlinks);
|
options = options.with_exists(true).with_resolve_symlinks(resolve_symlinks);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::iter::Rev;
|
use std::iter::Rev;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::{fs, path};
|
use std::{fs, path};
|
||||||
|
|
||||||
use glob::Pattern;
|
use glob::Pattern;
|
||||||
|
@ -40,6 +41,10 @@ impl<'a> Stream<'a> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.filter_by_basedir(&dir.path) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let dir = &self.db.dirs()[idx];
|
let dir = &self.db.dirs()[idx];
|
||||||
return Some(dir);
|
return Some(dir);
|
||||||
}
|
}
|
||||||
|
@ -91,6 +96,15 @@ impl<'a> Stream<'a> {
|
||||||
if self.options.resolve_symlinks { fs::symlink_metadata } else { fs::metadata };
|
if self.options.resolve_symlinks { fs::symlink_metadata } else { fs::metadata };
|
||||||
resolver(path).map(|metadata| metadata.is_dir()).unwrap_or_default()
|
resolver(path).map(|metadata| metadata.is_dir()).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn filter_by_basedir(&self, path: &str) -> bool {
|
||||||
|
if let Some(basedir) = &self.options.basedir {
|
||||||
|
let path = Path::new(path);
|
||||||
|
return path.starts_with(basedir);
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StreamOptions {
|
pub struct StreamOptions {
|
||||||
|
@ -112,6 +126,10 @@ pub struct StreamOptions {
|
||||||
/// Directories that do not exist and haven't been accessed since TTL will
|
/// Directories that do not exist and haven't been accessed since TTL will
|
||||||
/// be lazily removed.
|
/// be lazily removed.
|
||||||
ttl: Epoch,
|
ttl: Epoch,
|
||||||
|
|
||||||
|
/// Only return directories within this parent directory
|
||||||
|
/// Does not check if the path exists
|
||||||
|
basedir: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StreamOptions {
|
impl StreamOptions {
|
||||||
|
@ -123,6 +141,7 @@ impl StreamOptions {
|
||||||
exists: false,
|
exists: false,
|
||||||
resolve_symlinks: false,
|
resolve_symlinks: false,
|
||||||
ttl: now.saturating_sub(3 * MONTH),
|
ttl: now.saturating_sub(3 * MONTH),
|
||||||
|
basedir: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +168,11 @@ impl StreamOptions {
|
||||||
self.resolve_symlinks = resolve_symlinks;
|
self.resolve_symlinks = resolve_symlinks;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_basedir(mut self, basedir: Option<String>) -> Self {
|
||||||
|
self.basedir = basedir;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in New Issue