From f8899a4a9137e5087938ebff3b0813128ba823fd Mon Sep 17 00:00:00 2001 From: Tahaa-Dev Date: Fri, 17 Jul 2026 17:53:53 +0300 Subject: [PATCH] Add aliases to dir displays --- contrib/completions/_zoxide | 1 + contrib/completions/_zoxide.ps1 | 1 + contrib/completions/zoxide.bash | 2 +- contrib/completions/zoxide.elv | 1 + contrib/completions/zoxide.fish | 1 + contrib/completions/zoxide.nu | 1 + contrib/completions/zoxide.ts | 4 ++++ src/cmd/cmd.rs | 4 ++++ src/cmd/edit.rs | 16 ++++++++------ src/cmd/query.rs | 15 +++++++++++-- src/db/dir.rs | 37 ++++++++++++++++++++++++++------- src/util.rs | 14 ++++++++----- 12 files changed, 76 insertions(+), 21 deletions(-) diff --git a/contrib/completions/_zoxide b/contrib/completions/_zoxide index 6ed3bb9..2d57f9c 100644 --- a/contrib/completions/_zoxide +++ b/contrib/completions/_zoxide @@ -195,6 +195,7 @@ _arguments "${_arguments_options[@]}" : \ '(-i --interactive)--list[List all matching directories]' \ '-s[Print score with results]' \ '--score[Print score with results]' \ +'--aliases[Print aliases with results]' \ '-h[Print help]' \ '--help[Print help]' \ '-V[Print version]' \ diff --git a/contrib/completions/_zoxide.ps1 b/contrib/completions/_zoxide.ps1 index 8552066..52a8f46 100644 --- a/contrib/completions/_zoxide.ps1 +++ b/contrib/completions/_zoxide.ps1 @@ -166,6 +166,7 @@ Register-ArgumentCompleter -Native -CommandName 'zoxide' -ScriptBlock { [CompletionResult]::new('--list', '--list', [CompletionResultType]::ParameterName, 'List all matching directories') [CompletionResult]::new('-s', '-s', [CompletionResultType]::ParameterName, 'Print score with results') [CompletionResult]::new('--score', '--score', [CompletionResultType]::ParameterName, 'Print score with results') + [CompletionResult]::new('--aliases', '--aliases', [CompletionResultType]::ParameterName, 'Print aliases with results') [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version') diff --git a/contrib/completions/zoxide.bash b/contrib/completions/zoxide.bash index 76a67ee..24ffa9f 100644 --- a/contrib/completions/zoxide.bash +++ b/contrib/completions/zoxide.bash @@ -305,7 +305,7 @@ _zoxide() { return 0 ;; zoxide__subcmd__query) - opts="-a -i -l -s -h -V --all --interactive --list --score --exclude --base-dir --help --version [KEYWORDS]..." + opts="-a -i -l -s -h -V --all --interactive --list --score --aliases --exclude --base-dir --help --version [KEYWORDS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/contrib/completions/zoxide.elv b/contrib/completions/zoxide.elv index 1f5ba2f..b72e26b 100644 --- a/contrib/completions/zoxide.elv +++ b/contrib/completions/zoxide.elv @@ -148,6 +148,7 @@ set edit:completion:arg-completer[zoxide] = {|@words| cand --list 'List all matching directories' cand -s 'Print score with results' cand --score 'Print score with results' + cand --aliases 'Print aliases with results' cand -h 'Print help' cand --help 'Print help' cand -V 'Print version' diff --git a/contrib/completions/zoxide.fish b/contrib/completions/zoxide.fish index aa24023..df1ad3a 100644 --- a/contrib/completions/zoxide.fish +++ b/contrib/completions/zoxide.fish @@ -90,6 +90,7 @@ complete -c zoxide -n "__fish_zoxide_using_subcommand query" -s a -l all -d 'Sho 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 s -l score -d 'Print score with results' +complete -c zoxide -n "__fish_zoxide_using_subcommand query" -l aliases -d 'Print aliases with results' complete -c zoxide -n "__fish_zoxide_using_subcommand query" -s h -l help -d 'Print help' complete -c zoxide -n "__fish_zoxide_using_subcommand query" -s V -l version -d 'Print version' complete -c zoxide -n "__fish_zoxide_using_subcommand remove" -s h -l help -d 'Print help' diff --git a/contrib/completions/zoxide.nu b/contrib/completions/zoxide.nu index db0422c..c1f49ec 100644 --- a/contrib/completions/zoxide.nu +++ b/contrib/completions/zoxide.nu @@ -117,6 +117,7 @@ module completions { --interactive(-i) # Use interactive selection --list(-l) # List all matching directories --score(-s) # Print score with results + --aliases # Print aliases with results --exclude: path # Exclude the current directory --base-dir: path # Only search within this directory --help(-h) # Print help diff --git a/contrib/completions/zoxide.ts b/contrib/completions/zoxide.ts index 080dae3..9070556 100644 --- a/contrib/completions/zoxide.ts +++ b/contrib/completions/zoxide.ts @@ -350,6 +350,10 @@ const completion: Fig.Spec = { name: ["-s", "--score"], description: "Print score with results", }, + { + name: "--aliases", + description: "Print aliases with results", + }, { name: ["-h", "--help"], description: "Print help", diff --git a/src/cmd/cmd.rs b/src/cmd/cmd.rs index 108df68..73add2d 100644 --- a/src/cmd/cmd.rs +++ b/src/cmd/cmd.rs @@ -193,6 +193,10 @@ pub struct Query { #[clap(long, short)] pub score: bool, + /// Print aliases with results + #[clap(long)] + pub aliases: bool, + /// Exclude the current directory #[clap(long, value_hint = ValueHint::DirPath, value_name = "path")] pub exclude: Option, diff --git a/src/cmd/edit.rs b/src/cmd/edit.rs index 958b0fa..6fb7cc6 100644 --- a/src/cmd/edit.rs +++ b/src/cmd/edit.rs @@ -30,8 +30,12 @@ impl Run for Edit { let stdout = &mut io::stdout().lock(); for dir in db.dirs().iter().rev() { - write!(stdout, "{}\0", dir.display().with_score(now).with_separator('\t')) - .pipe_exit("fzf")?; + write!( + stdout, + "{}\0", + dir.display().with_score(now).with_aliases(true).with_separator('\t') + ) + .pipe_exit("fzf")?; } Ok(()) } @@ -57,9 +61,9 @@ impl Edit { "--bind=\ btab:up,\ ctrl-r:reload(zoxide edit reload),\ -ctrl-d:reload(zoxide edit delete {2..}),\ -ctrl-w:reload(zoxide edit increment {2..}),\ -ctrl-s:reload(zoxide edit decrement {2..}),\ +ctrl-d:reload(zoxide edit delete {3..}),\ +ctrl-w:reload(zoxide edit increment {3..}),\ +ctrl-s:reload(zoxide edit decrement {3..}),\ ctrl-z:ignore,\ double-click:ignore,\ enter:abort,\ @@ -74,7 +78,7 @@ tab:down", ctrl-r:reload \tctrl-d:delete ctrl-w:increment\tctrl-s:decrement - SCORE\tPATH", + SCORE\tALIASES\tPATH", "--info=inline", "--layout=reverse", "--padding=1,0,0,0", diff --git a/src/cmd/query.rs b/src/cmd/query.rs index 6539c2e..282ce4c 100644 --- a/src/cmd/query.rs +++ b/src/cmd/query.rs @@ -35,7 +35,8 @@ impl Query { match stream.next() { Some(dir) if Some(dir.path.as_ref()) == self.exclude.as_deref() => continue, Some(dir) => { - if let Some(selection) = fzf.write(dir, now)? { + // Always enable aliases for interactive queries + if let Some(selection) = fzf.write(dir, now, true)? { break selection; } } @@ -45,9 +46,17 @@ impl Query { if self.score { print!("{selection}"); - } else { + } else if self.aliases { let path = selection.get(7..).context("could not read selection from fzf")?; print!("{path}"); + } else { + let path = selection + .get(7..) + .map(|path| { + path.get(path.find('\t').map(|idx| idx + 1).unwrap_or(0)..).unwrap_or(path) + }) + .context("could not read selection from fzf")?; + print!("{path}"); } Ok(()) } @@ -59,6 +68,7 @@ impl Query { continue; } let dir = if self.score { dir.display().with_score(now) } else { dir.display() }; + let dir = if self.aliases { dir.with_aliases(self.aliases) } else { dir }; writeln!(handle, "{dir}").pipe_exit("stdout")?; } Ok(()) @@ -73,6 +83,7 @@ impl Query { } let dir = if self.score { dir.display().with_score(now) } else { dir.display() }; + let dir = if self.aliases { dir.with_aliases(self.aliases) } else { dir }; writeln!(handle, "{dir}").pipe_exit("stdout") } diff --git a/src/db/dir.rs b/src/db/dir.rs index d0d37a4..43d6448 100644 --- a/src/db/dir.rs +++ b/src/db/dir.rs @@ -23,12 +23,13 @@ pub struct DirV3<'a> { pub last_accessed: Epoch, } -pub trait Dir<'a> { +pub trait Dir { fn path(&self) -> &str; fn score(&self, now: Epoch) -> Rank; + fn aliases(&self) -> &[Cow<'_, str>]; } -impl Dir<'_> for DirV4<'_> { +impl Dir for DirV4<'_> { fn path(&self) -> &str { &self.path } @@ -46,6 +47,10 @@ impl Dir<'_> for DirV4<'_> { self.rank * 0.25 } } + + fn aliases(&self) -> &[Cow<'_, str>] { + &self.aliases + } } impl DirV4<'_> { @@ -54,7 +59,7 @@ impl DirV4<'_> { } } -impl Dir<'_> for DirV3<'_> { +impl Dir for DirV3<'_> { fn path(&self) -> &str { &self.path } @@ -72,17 +77,22 @@ impl Dir<'_> for DirV3<'_> { self.rank * 0.25 } } + + fn aliases(&self) -> &[Cow<'_, str>] { + return &[]; + } } -pub struct DirDisplay<'a, T: Dir<'a>> { +pub struct DirDisplay<'a, T: Dir> { dir: &'a T, now: Option, separator: char, + aliases: bool, } -impl<'a, T: Dir<'a>> DirDisplay<'a, T> { +impl<'a, T: Dir> DirDisplay<'a, T> { fn new(dir: &'a T) -> Self { - Self { dir, separator: ' ', now: None } + Self { dir, separator: ' ', now: None, aliases: false } } pub fn with_score(mut self, now: Epoch) -> Self { @@ -94,14 +104,27 @@ impl<'a, T: Dir<'a>> DirDisplay<'a, T> { self.separator = separator; self } + + pub fn with_aliases(mut self, enable: bool) -> Self { + self.aliases = enable; + self + } } -impl<'a, T: Dir<'a>> Display for DirDisplay<'a, T> { +impl<'a, T: Dir> Display for DirDisplay<'a, T> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { if let Some(now) = self.now { let score = self.dir.score(now).clamp(0.0, 9999.0); write!(f, "{score:>6.1}{}", self.separator)?; } + + if self.aliases { + for alias in self.dir.aliases() { + write!(f, "{} ", alias)?; + } + write!(f, "{}", self.separator)?; + } + write!(f, "{}", self.dir.path()) } } diff --git a/src/util.rs b/src/util.rs index d26d4a8..9b59f27 100644 --- a/src/util.rs +++ b/src/util.rs @@ -41,7 +41,7 @@ impl Fzf { cmd.args([ // Search mode "--delimiter=\t", - "--nth=2", + "--nth=3", // Scripting "--read0", ]) @@ -60,9 +60,9 @@ impl Fzf { self.args([ // Non-POSIX args are only available on certain operating systems. if cfg!(target_os = "linux") { - r"--preview=\command -p ls -Cp --color=always --group-directories-first {2..}" + r"--preview=\command -p ls -Cp --color=always --group-directories-first {3..}" } else { - r"--preview=\command -p ls -Cp {2..}" + r"--preview=\command -p ls -Cp {3..}" }, // Rounded edges don't display correctly on some terminals. "--preview-window=down,30%,sharp", @@ -121,9 +121,13 @@ impl Fzf { pub struct FzfChild(Child); impl FzfChild { - pub fn write(&mut self, dir: &DirV4, now: Epoch) -> Result> { + pub fn write(&mut self, dir: &DirV4, now: Epoch, aliases: bool) -> Result> { let handle = self.0.stdin.as_mut().unwrap(); - match write!(handle, "{}\0", dir.display().with_score(now).with_separator('\t')) { + match write!( + handle, + "{}\0", + dir.display().with_score(now).with_aliases(aliases).with_separator('\t') + ) { Ok(()) => Ok(None), Err(e) if e.kind() == io::ErrorKind::BrokenPipe => self.wait().map(Some), Err(e) => Err(e).context("could not write to fzf"),