From b161a45bfdfc096bd66195975988aa6287159aa5 Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Mon, 8 Sep 2025 19:56:58 +0200 Subject: [PATCH] Install the zoxide plugin --- completions/zoxide.fish | 41 +++++++++++++++++++++++++ conf.d/zoxide.fish | 66 ++++++++++++++++++++++++++++++++++++++++- fish_plugins | 1 + functions/zoxide.fish | 43 +++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 completions/zoxide.fish create mode 100644 functions/zoxide.fish diff --git a/completions/zoxide.fish b/completions/zoxide.fish new file mode 100644 index 0000000..3c2dad7 --- /dev/null +++ b/completions/zoxide.fish @@ -0,0 +1,41 @@ +set -l commands add help import init query remove + +# disable normal all-files completion +complete -c zoxide -f + +# onyl show base options if none was used already +complete -c zoxide -n __fish_use_subcommand -a add -d "Add a new directory or increment its rank" +complete -c zoxide -n __fish_use_subcommand -a help -d "Prints this message or the help of the given subcommand(s)" +complete -c zoxide -n __fish_use_subcommand -a import -d "Import from z database" +complete -c zoxide -n __fish_use_subcommand -a init -d "Generates shell configuration" +complete -c zoxide -n __fish_use_subcommand -a query -d "Search for a directory" +complete -c zoxide -n __fish_use_subcommand -a remove -d "Remove a directory" + +# zoxide add +complete -c zoxide -n "_zoxide_equals_first_token add" -n "__fish_is_nth_token 2" -a "(__fish_complete_directories)" + +# zoxide help +complete -c zoxide -n "_zoxide_equals_first_token help" -n "__fish_is_nth_token 2" -a "$commands" + +# zoxide import +complete -c zoxide -r -F -n "_zoxide_equals_first_token import" -n "__fish_is_nth_token 2" +complete -c zoxide -r -n "_zoxide_equals_first_token import" -l merge -d "Merge entries into existing database" + +# zoxide init +set -l initshells bash fish posix powershell zsh +complete -c zoxide -n "_zoxide_equals_first_token init" -n "__fish_is_nth_token 2" -a "$initshells" +complete -c zoxide -n "_zoxide_equals_first_token init" -l cmd -d "Renames the 'z' command and corresponding aliases [default: z]" +complete -c zoxide -n "_zoxide_equals_first_token init" -l hook -a "none prompt pwd" -d "Chooses event on which an entry is added to the database [default: pwd]" +complete -c zoxide -n "_zoxide_equals_first_token init" -l no-aliases -d "Prevents zoxide from defining any commands other than 'z'" + +# zoxide query +complete -c zoxide -r -n "_zoxide_equals_first_token query" -s i -l interactive -d "Opens an interactive selection menu using fzf" +complete -c zoxide -r -n "_zoxide_equals_first_token query" -s l -l list -d "List all matching directories" +complete -c zoxide -r -n "_zoxide_equals_first_token query" -s s -l score -d "Display score along with result" + +# zoxide remove +complete -c zoxide -n "_zoxide_equals_first_token remove" -n "__fish_is_nth_token 2" -a "(zoxide query -l)" + +# Always possible +complete -c zoxide -x -s h -l help -d "Prints help information" +complete -c zoxide -x -s V -l version -d "Prints version information" diff --git a/conf.d/zoxide.fish b/conf.d/zoxide.fish index 2e9cc17..ba17e9e 100644 --- a/conf.d/zoxide.fish +++ b/conf.d/zoxide.fish @@ -1 +1,65 @@ -zoxide init fish | source +if status is-interactive + + if type -q zoxide + + # ------------- + # 'zoxide init fish' is very different for different versions of zoxide + # to guarantee the same behavior we define these functions ourself, + # especially because the apt package is so old + # most of these functions were taken from https://github.com/ajeetdsouza/zoxide + # from version 0.8.1 + + if ! builtin functions -q _zoxide_cd + if builtin functions -q cd + builtin functions -c cd _zoxide_cd + else + alias _zoxide_cd='builtin cd' + end + end + + function _zoxide_hook --on-variable PWD + test -z "$fish_private_mode" + and command zoxide add -- (builtin pwd -L) + end + + function z + set argc (count $argv) + if test $argc -eq 0 + _zoxide_cd $HOME + else if test "$argv" = - + _zoxide_cd - + else if test -d $argv[-1] + _zoxide_cd $argv[-1] + else + set -l result (command zoxide query $argv) + and _zoxide_cd $result + end + end + + function zi + set -l result (command zoxide query -i -- $argv) + and _zoxide_cd $result + end + + # ------------- + + alias cd=z + + # use custom completion + complete -c z -f # disable files by default + complete -c z -x -a '(_zoxide_z_complete)' + else + echo "[plugin: zoxide] Command 'zoxide' cannot be found. Not installed or not in path" + end + +end + +function _zoxide_uninstall --on-event zoxide_uninstall + if alias | grep "alias cd z" >/dev/null + functions -e cd + end + if builtin functions -q _zoxide_cd && not functions -q cd + # restore old cd + builtin functions -c _zoxide_cd cd + end +end diff --git a/fish_plugins b/fish_plugins index 44ba441..f1248d9 100644 --- a/fish_plugins +++ b/fish_plugins @@ -3,3 +3,4 @@ edc/bass jorgebucaran/fisher shinriyo/breeze ilancosman/tide@v6 +icezyclon/zoxide.fish diff --git a/functions/zoxide.fish b/functions/zoxide.fish new file mode 100644 index 0000000..1e0fda5 --- /dev/null +++ b/functions/zoxide.fish @@ -0,0 +1,43 @@ +function _zoxide_z_complete -d "Complete directory first or zoxide queries otherwise" --argument-names comp desc + # most of this functions is compied from __fish_complete_directories with a small tweak + + # comp is the currently completing token + if not set -q comp[1] + set comp (commandline -ct) + end + # cmd are all tokens including the current one except the command + set -l cmd (commandline -opc) $comp + set -e cmd[1] + + if test "$comp" = "$cmd" + # if we are on our first token, then allow file complete + # otherwise use zoxide (for multi word zoxide query) + + # HACK: We call into the file completions by using a non-existent command. + # If we used e.g. `ls`, we'd run the risk of completing its options or another kind of argument. + # But since we default to file completions, if something doesn't have another completion... + set -f dirs (complete -C"nonexistentcommandooheehoohaahaahdingdongwallawallabingbang $comp" | string match -r '.*/$') + end + + # in the future: replace entire cmd with tab complete instead of only last token + # at the moment: is handled in z function to always enter last token if directory + + if set -q dirs[1] + # if we find any files to complete use those + printf "%s\t$desc\n" $dirs + else + # otherwise use zoxide + zoxide query -l $cmd + end +end + +function _zoxide_equals_first_token -a check -d "Test if first non-switch token equals given one" + set -l tokens (commandline -co) + set -e tokens[1] + set -l tokens (string replace -r --filter '^([^-].*)' '$1' -- $tokens) + if set -q tokens[1] + test $tokens[1] = $check + else + return 1 + end +end