Add core alias support additions and structural changes

This commit is contained in:
Tahaa-Dev 2026-07-13 04:41:52 +03:00 committed by Taha Mahmoud
parent ee594e6906
commit f433f9ad84
16 changed files with 102 additions and 17 deletions

View File

@ -32,6 +32,8 @@ _zoxide() {
_arguments "${_arguments_options[@]}" : \
'-s+[The rank to increment the entry if it exists or initialize it with if it doesn'\''t]:SCORE:_default' \
'--score=[The rank to increment the entry if it exists or initialize it with if it doesn'\''t]:SCORE:_default' \
'-a+[]:ALIAS:_default' \
'--alias=[]:ALIAS:_default' \
'-h[Print help]' \
'--help[Print help]' \
'-V[Print version]' \

View File

@ -36,6 +36,8 @@ Register-ArgumentCompleter -Native -CommandName 'zoxide' -ScriptBlock {
'zoxide;add' {
[CompletionResult]::new('-s', '-s', [CompletionResultType]::ParameterName, 'The rank to increment the entry if it exists or initialize it with if it doesn''t')
[CompletionResult]::new('--score', '--score', [CompletionResultType]::ParameterName, 'The rank to increment the entry if it exists or initialize it with if it doesn''t')
[CompletionResult]::new('-a', '-a', [CompletionResultType]::ParameterName, 'a')
[CompletionResult]::new('--alias', '--alias', [CompletionResultType]::ParameterName, 'alias')
[CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version')

View File

@ -85,7 +85,7 @@ _zoxide() {
return 0
;;
zoxide__subcmd__add)
opts="-s -h -V --score --help --version <PATHS>..."
opts="-s -a -h -V --score --alias --help --version <PATHS>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -99,6 +99,14 @@ _zoxide() {
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--alias)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-a)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;

View File

@ -32,6 +32,8 @@ set edit:completion:arg-completer[zoxide] = {|@words|
&'zoxide;add'= {
cand -s 'The rank to increment the entry if it exists or initialize it with if it doesn''t'
cand --score 'The rank to increment the entry if it exists or initialize it with if it doesn''t'
cand -a 'a'
cand --alias 'alias'
cand -h 'Print help'
cand --help 'Print help'
cand -V 'Print version'

View File

@ -33,6 +33,7 @@ complete -c zoxide -n "__fish_zoxide_needs_command" -f -a "init" -d 'Generate sh
complete -c zoxide -n "__fish_zoxide_needs_command" -f -a "query" -d 'Search for a directory in the database'
complete -c zoxide -n "__fish_zoxide_needs_command" -f -a "remove" -d 'Remove a directory from the database'
complete -c zoxide -n "__fish_zoxide_using_subcommand add" -s s -l score -d 'The rank to increment the entry if it exists or initialize it with if it doesn\'t' -r
complete -c zoxide -n "__fish_zoxide_using_subcommand add" -s a -l alias -r
complete -c zoxide -n "__fish_zoxide_using_subcommand add" -s h -l help -d 'Print help'
complete -c zoxide -n "__fish_zoxide_using_subcommand add" -s V -l version -d 'Print version'
complete -c zoxide -n "__fish_zoxide_using_subcommand edit; and not __fish_seen_subcommand_from decrement delete increment reload" -s h -l help -d 'Print help'

View File

@ -9,6 +9,7 @@ module completions {
# Add a new directory or increment its rank
export extern "zoxide add" [
--score(-s): string # The rank to increment the entry if it exists or initialize it with if it doesn't
--alias(-a): string
--help(-h) # Print help
--version(-V) # Print version
...paths: path

View File

@ -15,6 +15,14 @@ const completion: Fig.Spec = {
isOptional: true,
},
},
{
name: ["-a", "--alias"],
isRepeatable: true,
args: {
name: "alias",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help",

View File

@ -18,6 +18,7 @@ impl Run for Add {
let mut db = Database::open()?;
let mut first = true;
for path in &self.paths {
let path =
if config::resolve_symlinks() { util::canonicalize } else { util::resolve_path }(
@ -35,7 +36,9 @@ impl Run for Add {
}
let by = self.score.unwrap_or(1.0);
db.add_update(path, by, now);
let alias = if first { self.alias.clone() } else { None };
db.add_update(path, by, now, alias);
first = false;
}
if db.dirty() {

View File

@ -63,6 +63,9 @@ pub struct Add {
/// doesn't
#[clap(short, long)]
pub score: Option<f64>,
#[clap(short, long)]
pub alias: Option<String>,
}
/// Edit the database

View File

@ -15,11 +15,15 @@ impl Run for Edit {
match &self.cmd {
Some(cmd) => {
match cmd {
EditCommand::Decrement { path } => db.add(path, -1.0, now),
EditCommand::Decrement { path } => {
db.add(path, -1.0, now, Option::<String>::None)
}
EditCommand::Delete { path } => {
db.remove(path);
}
EditCommand::Increment { path } => db.add(path, 1.0, now),
EditCommand::Increment { path } => {
db.add(path, 1.0, now, Option::<String>::None)
}
EditCommand::Reload => {}
}
db.save()?;

View File

@ -11,6 +11,8 @@ pub struct Dir<'a> {
pub path: Cow<'a, str>,
pub rank: Rank,
pub last_accessed: Epoch,
#[serde(default)]
pub aliases: Vec<Cow<'a, str>>,
}
impl Dir<'_> {

View File

@ -65,11 +65,31 @@ impl Database {
}
/// Increments the rank of a directory, or creates it if it does not exist.
pub fn add(&mut self, path: impl AsRef<str> + Into<String>, by: Rank, now: Epoch) {
pub fn add(
&mut self,
path: impl AsRef<str> + Into<String>,
by: Rank,
now: Epoch,
alias: Option<impl AsRef<str> + Into<String>>,
) {
self.with_dirs_mut(|dirs| match dirs.iter_mut().find(|dir| dir.path == path.as_ref()) {
Some(dir) => dir.rank = (dir.rank + by).max(0.0),
Some(dir) => {
dir.rank = (dir.rank + by).max(0.0);
if let Some(al) = alias {
dir.aliases.push(al.into().into());
}
}
None => {
dirs.push(Dir { path: path.into().into(), rank: by.max(0.0), last_accessed: now })
let mut aliases = Vec::new();
if let Some(al) = alias {
aliases.push(al.into().into());
}
dirs.push(Dir {
path: path.into().into(),
rank: by.max(0.0),
last_accessed: now,
aliases,
})
}
});
self.with_dirty_mut(|dirty| *dirty = true);
@ -79,23 +99,51 @@ impl Database {
/// directory is already in the database, it is expected that the user
/// either does a check before calling this, or calls `dedup()`
/// afterward.
pub fn add_unchecked(&mut self, path: impl AsRef<str> + Into<String>, rank: Rank, now: Epoch) {
pub fn add_unchecked(
&mut self,
path: impl AsRef<str> + Into<String>,
rank: Rank,
now: Epoch,
alias: Option<impl AsRef<str> + Into<String>>,
) {
self.with_dirs_mut(|dirs| {
dirs.push(Dir { path: path.into().into(), rank, last_accessed: now })
let mut aliases = Vec::new();
if let Some(al) = alias {
aliases.push(al.into().into());
}
dirs.push(Dir { path: path.into().into(), rank, last_accessed: now, aliases })
});
self.with_dirty_mut(|dirty| *dirty = true);
}
/// Increments the rank and updates the last_accessed of a directory, or
/// creates it if it does not exist.
pub fn add_update(&mut self, path: impl AsRef<str> + Into<String>, by: Rank, now: Epoch) {
pub fn add_update(
&mut self,
path: impl AsRef<str> + Into<String>,
by: Rank,
now: Epoch,
alias: Option<impl AsRef<str> + Into<String>>,
) {
self.with_dirs_mut(|dirs| match dirs.iter_mut().find(|dir| dir.path == path.as_ref()) {
Some(dir) => {
dir.rank = (dir.rank + by).max(0.0);
dir.last_accessed = now;
if let Some(al) = alias {
dir.aliases.push(al.into().into());
}
}
None => {
dirs.push(Dir { path: path.into().into(), rank: by.max(0.0), last_accessed: now })
let mut aliases = Vec::new();
if let Some(al) = alias {
aliases.push(al.into().into());
}
dirs.push(Dir {
path: path.into().into(),
rank: by.max(0.0),
last_accessed: now,
aliases,
})
}
});
self.with_dirty_mut(|dirty| *dirty = true);
@ -244,8 +292,8 @@ mod tests {
{
let mut db = Database::open_dir(data_dir.path()).unwrap();
db.add(path, 1.0, now);
db.add(path, 1.0, now);
db.add(path, 1.0, now, Option::<String>::None);
db.add(path, 1.0, now, Some(String::from("foo")));
db.save().unwrap();
}
@ -268,7 +316,7 @@ mod tests {
{
let mut db = Database::open_dir(data_dir.path()).unwrap();
db.add(path, 1.0, now);
db.add(path, 1.0, now, Option::<String>::None);
db.save().unwrap();
}

View File

@ -60,7 +60,7 @@ pub(crate) fn run(importer: &impl Importer, db: &mut Database) -> Result<()> {
if exclude_dirs.iter().any(|glob| glob.matches(&dir.path)) {
continue;
}
db.add_unchecked(dir.path, dir.rank, dir.last_accessed);
db.add_unchecked(dir.path, dir.rank, dir.last_accessed, Option::<String>::None);
}
Err(e) => {
let location = match &e.path {

View File

@ -64,6 +64,7 @@ impl Iter {
path: Cow::Owned(path.to_string()),
rank: 1.0,
last_accessed: timestamp as Epoch,
aliases: Vec::new(),
};
Ok(dir)
}

View File

@ -52,7 +52,7 @@ impl<R: BufRead> Iter<R> {
// take a while to normalize.
let rank = sigmoid(rank);
Ok(Dir { path: Cow::Owned(path.to_string()), rank, last_accessed: 0 })
Ok(Dir { path: Cow::Owned(path.to_string()), rank, last_accessed: 0, aliases: Vec::new() })
}
}

View File

@ -54,7 +54,7 @@ impl<R: BufRead> Iter<R> {
let path = split.next().ok_or_else(err)?;
Ok(Dir { path: Cow::Owned(path.to_string()), rank, last_accessed })
Ok(Dir { path: Cow::Owned(path.to_string()), rank, last_accessed, aliases: Vec::new() })
}
}