cmd/query: Add `--sort-by` option
Added the option `--sort-by [score|path|last-accessed]` for the `query` subcommand with default value `score` i.e: ```bash $ zoxide query --list --score --sort-by last-accessed 4.0 /home/martin/playground/scala/scala-3-project-template 3.5 /home/martin/playground/rust 3.8 /home/martin/playground/python 12.0 /home/martin/projects/zoxide 11.8 /home/martin/playground 16.5 /home/martin/projects/thesis 6.0 /home/martin/projects/thesis/frontend ... ``` ```bash $ zoxide query --list --score --sort-by path 0.2 /home/martin/.local/state 0.2 /home/martin/.local/share/zoxide 0.2 /home/martin/.local/share 0.2 /home/martin/.config/protonmail/bridge-v3 0.2 /home/martin/.config/protonmail 0.5 /home 0.5 /etc/nixos/lib/lisp 0.8 / ... ``` ```bash $ zoxide query --list --score 16.5 /home/martin/projects/thesis 16.0 /home/martin/projects/zoxide 8.0 /home/martin/projects/egcd 8.0 /persist 6.0 /home/martin/projects/thesis/frontend ... ``` Fixes #784 as well as #815.
This commit is contained in:
parent
8da8f50eaa
commit
ac98f4044c
|
|
@ -117,6 +117,7 @@ _arguments "${_arguments_options[@]}" \
|
|||
;;
|
||||
(query)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
'--sort-by=[Sort result]:SORT_BY:(path score last-accessed)' \
|
||||
'--exclude=[Exclude the current directory]:path:_files -/' \
|
||||
'-a[Show unavailable directories]' \
|
||||
'--all[Show unavailable directories]' \
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ Register-ArgumentCompleter -Native -CommandName 'zoxide' -ScriptBlock {
|
|||
break
|
||||
}
|
||||
'zoxide;query' {
|
||||
[CompletionResult]::new('--sort-by', 'sort-by', [CompletionResultType]::ParameterName, 'Sort result')
|
||||
[CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'Exclude the current directory')
|
||||
[CompletionResult]::new('-a', 'a', [CompletionResultType]::ParameterName, 'Show unavailable directories')
|
||||
[CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'Show unavailable directories')
|
||||
|
|
|
|||
|
|
@ -187,12 +187,16 @@ _zoxide() {
|
|||
return 0
|
||||
;;
|
||||
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 --sort-by --score --exclude --help --version [KEYWORDS]..."
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
fi
|
||||
case "${prev}" in
|
||||
--sort-by)
|
||||
COMPREPLY=($(compgen -W "path score last-accessed" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--exclude)
|
||||
COMPREPLY=()
|
||||
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ set edit:completion:arg-completer[zoxide] = {|@words|
|
|||
cand --version 'Print version'
|
||||
}
|
||||
&'zoxide;query'= {
|
||||
cand --sort-by 'Sort result'
|
||||
cand --exclude 'Exclude the current directory'
|
||||
cand -a 'Show unavailable directories'
|
||||
cand --all 'Show unavailable directories'
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ complete -c zoxide -n "__fish_seen_subcommand_from init" -l hook -d 'Changes how
|
|||
complete -c zoxide -n "__fish_seen_subcommand_from init" -l no-cmd -d 'Prevents zoxide from defining the `z` and `zi` commands'
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from init" -s h -l help -d 'Print help'
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from init" -s V -l version -d 'Print version'
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from query" -l sort-by -d 'Sort result' -r -f -a "{path '',score '',last-accessed ''}"
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from query" -l exclude -d 'Exclude the current directory' -r -f -a "(__fish_complete_directories)"
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from query" -s a -l all -d 'Show unavailable directories'
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from query" -s i -l interactive -d 'Use interactive selection'
|
||||
|
|
|
|||
|
|
@ -194,6 +194,20 @@ const completion: Fig.Spec = {
|
|||
name: "query",
|
||||
description: "Search for a directory in the database",
|
||||
options: [
|
||||
{
|
||||
name: "--sort-by",
|
||||
description: "Sort result",
|
||||
isRepeatable: true,
|
||||
args: {
|
||||
name: "sort_by",
|
||||
isOptional: true,
|
||||
suggestions: [
|
||||
"path",
|
||||
"score",
|
||||
"last-accessed",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "--exclude",
|
||||
description: "Exclude the current directory",
|
||||
|
|
|
|||
|
|
@ -165,6 +165,10 @@ pub struct Query {
|
|||
#[clap(long, short, conflicts_with = "interactive")]
|
||||
pub list: bool,
|
||||
|
||||
/// Sort result
|
||||
#[clap(long)]
|
||||
pub sort_by: Option<Ordering>,
|
||||
|
||||
/// Print score with results
|
||||
#[clap(long, short)]
|
||||
pub score: bool,
|
||||
|
|
@ -174,6 +178,13 @@ pub struct Query {
|
|||
pub exclude: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(ValueEnum, Debug, Clone, Copy)]
|
||||
pub enum Ordering {
|
||||
Path,
|
||||
Score,
|
||||
LastAccessed,
|
||||
}
|
||||
|
||||
/// Remove a directory from the database
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::io::{self, Write};
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use super::Ordering;
|
||||
use crate::cmd::{Query, Run};
|
||||
use crate::config;
|
||||
use crate::db::{Database, Epoch, Stream, StreamOptions};
|
||||
|
|
@ -18,7 +19,8 @@ impl Run for Query {
|
|||
impl Query {
|
||||
fn query(&self, db: &mut Database) -> Result<()> {
|
||||
let now = util::current_time()?;
|
||||
let mut stream = self.get_stream(db, now)?;
|
||||
let ordering = self.sort_by;
|
||||
let mut stream = self.get_stream(db, now, ordering)?;
|
||||
|
||||
if self.interactive {
|
||||
self.query_interactive(&mut stream, now)
|
||||
|
|
@ -76,10 +78,16 @@ impl Query {
|
|||
writeln!(handle, "{dir}").pipe_exit("stdout")
|
||||
}
|
||||
|
||||
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,
|
||||
ordering: Option<Ordering>,
|
||||
) -> Result<Stream<'a>> {
|
||||
let mut options = StreamOptions::new(now)
|
||||
.with_keywords(self.keywords.iter().map(|s| s.as_str()))
|
||||
.with_exclude(config::exclude_dirs()?);
|
||||
.with_exclude(config::exclude_dirs()?)
|
||||
.sort_by(ordering);
|
||||
if !self.all {
|
||||
let resolve_symlinks = config::resolve_symlinks();
|
||||
options = options.with_exists(true).with_resolve_symlinks(resolve_symlinks);
|
||||
|
|
|
|||
|
|
@ -178,6 +178,15 @@ impl Database {
|
|||
self.with_dirty_mut(|dirty| *dirty = true);
|
||||
}
|
||||
|
||||
pub fn sort_by_last_accessed(&mut self) {
|
||||
self.with_dirs_mut(|dirs| {
|
||||
dirs.sort_unstable_by(|dir1: &Dir, dir2: &Dir| {
|
||||
dir1.last_accessed.cmp(&dir2.last_accessed)
|
||||
})
|
||||
});
|
||||
self.with_dirty_mut(|dirty| *dirty = true);
|
||||
}
|
||||
|
||||
pub fn dirty(&self) -> bool {
|
||||
*self.borrow_dirty()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use std::{fs, path};
|
|||
|
||||
use glob::Pattern;
|
||||
|
||||
use crate::cmd::Ordering;
|
||||
use crate::db::{Database, Dir, Epoch};
|
||||
use crate::util::{self, MONTH};
|
||||
|
||||
|
|
@ -15,7 +16,11 @@ pub struct Stream<'a> {
|
|||
|
||||
impl<'a> Stream<'a> {
|
||||
pub fn new(db: &'a mut Database, options: StreamOptions) -> Self {
|
||||
db.sort_by_score(options.now);
|
||||
match options.sort_by {
|
||||
Ordering::Path => db.sort_by_path(),
|
||||
Ordering::Score => db.sort_by_score(options.now),
|
||||
Ordering::LastAccessed => db.sort_by_last_accessed(),
|
||||
}
|
||||
let idxs = (0..db.dirs().len()).rev();
|
||||
Stream { db, idxs, options }
|
||||
}
|
||||
|
|
@ -108,6 +113,9 @@ pub struct StreamOptions {
|
|||
/// Directories that do not exist and haven't been accessed since TTL will
|
||||
/// be lazily removed.
|
||||
ttl: Epoch,
|
||||
|
||||
/// Ordering of the stream entries
|
||||
sort_by: Ordering,
|
||||
}
|
||||
|
||||
impl StreamOptions {
|
||||
|
|
@ -119,6 +127,7 @@ impl StreamOptions {
|
|||
exists: false,
|
||||
resolve_symlinks: false,
|
||||
ttl: now.saturating_sub(3 * MONTH),
|
||||
sort_by: Ordering::Score,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,6 +154,13 @@ impl StreamOptions {
|
|||
self.resolve_symlinks = resolve_symlinks;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn sort_by(mut self, ordering: Option<Ordering>) -> Self {
|
||||
if let Some(o) = ordering {
|
||||
self.sort_by = o
|
||||
};
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue