From 329cd7d42975e19cc677be489b9ca928217f7001 Mon Sep 17 00:00:00 2001 From: Fabian Boehm Date: Tue, 25 Mar 2025 20:26:23 +0100 Subject: [PATCH] Make functions, completions and tests resilient to running on an embed-data fish In case a completion needs a function from another script, run `complete -C"foo "` to load it, so the full autoloading logic is used. Otherwise these things break if the path is off. E.g. cargo's version will fail if you override the cargo completion in ~/.config/fish/completions without also overriding the rustup completions. In other cases, fix for empty $__fish_data_dir, which will be coming in the next commit --- share/completions/cargo.fish | 2 +- share/completions/gitk.fish | 3 ++- share/completions/npm.fish | 2 +- share/completions/nvim.fish | 2 +- share/completions/pre-commit.fish | 2 +- share/completions/tig.fish | 2 +- share/completions/yarn.fish | 2 +- share/functions/__fish_npm_helper.fish | 4 ++++ share/functions/__fish_print_help.fish | 8 ++++---- tests/checks/check-all-fish-files.fish | 3 ++- tests/checks/functions.fish | 4 ++-- tests/checks/no-config.fish | 5 ++--- tests/checks/type.fish | 2 +- 13 files changed, 23 insertions(+), 18 deletions(-) diff --git a/share/completions/cargo.fish b/share/completions/cargo.fish index 286474bf6..cb57abf05 100644 --- a/share/completions/cargo.fish +++ b/share/completions/cargo.fish @@ -29,7 +29,7 @@ end # have an easy way to do that in the `complete` machinery at this time. function __fish_cargo_targets if command -q rustup - functions -q __rustup_installed_targets || source (path dirname (status current-filename))/rustup.fish + functions -q __rustup_installed_targets || complete -C"rustup " &>/dev/null __rustup_installed_targets else rustc --print target-list diff --git a/share/completions/gitk.fish b/share/completions/gitk.fish index 55b4b4a19..f309f745f 100644 --- a/share/completions/gitk.fish +++ b/share/completions/gitk.fish @@ -1,6 +1,7 @@ # gitk - The Git repository browser -source $__fish_data_dir/completions/git.fish +# for __fish_git_ranges and __fish_git_refs +complete -C"git " >/dev/null complete -c gitk -n 'not contains -- -- (commandline -xpc)' -l all -d 'Show all refs (branches, tags, etc.)' complete -c gitk -n 'not contains -- -- (commandline -xpc)' -l since=YYYY-MM-DD -x -d 'Show commits more recent that a specific date' diff --git a/share/completions/npm.fish b/share/completions/npm.fish index 6ae1b0c26..7de2a6f49 100644 --- a/share/completions/npm.fish +++ b/share/completions/npm.fish @@ -4,7 +4,7 @@ # see also Fish's large set of completions for examples: # https://github.com/fish-shell/fish-shell/tree/master/share/completions -source $__fish_data_dir/functions/__fish_npm_helper.fish +__fish_npm_helper set -l npm_install "npm install --global" function __fish_npm_needs_command diff --git a/share/completions/nvim.fish b/share/completions/nvim.fish index be8b27a70..419597411 100644 --- a/share/completions/nvim.fish +++ b/share/completions/nvim.fish @@ -1,4 +1,4 @@ -type --quiet __fish_vim_tags || source (status dirname)/vim.fish +complete -C"vim " &>/dev/null # Options shared with vim, copied from vim.fish complete -c nvim -s c -r -d 'Execute Ex command after the first file has been read' diff --git a/share/completions/pre-commit.fish b/share/completions/pre-commit.fish index b128e4749..c7f31f83b 100644 --- a/share/completions/pre-commit.fish +++ b/share/completions/pre-commit.fish @@ -2,7 +2,7 @@ set -l commands autoupdate clean gc init-templatedir install install-hooks migra set -l hook_stages commit merge-commit prepare-commit-msg commit-msg post-commit manual post-checkout push post-merge post-rewrite set -l hook_types pre-commit pre-merge-commit pre-push prepare-commit-msg commit-msg post-commit post-checkout post-merge post-rewrite -functions -q __fish_git || source $__fish_data_dir/completions/git.fish +functions -q __fish_git || complete -C"git " &>/dev/null function __fish_pre_commit_config_print -a key set -l config (__fish_git rev-parse --show-toplevel 2>/dev/null)/.pre-commit-config.yaml diff --git a/share/completions/tig.fish b/share/completions/tig.fish index 78b070f66..358e0d9d8 100644 --- a/share/completions/tig.fish +++ b/share/completions/tig.fish @@ -1,6 +1,6 @@ # tig - text-mode interface for Git -not functions -q __fish_git && source $__fish_data_dir/completions/git.fish +functions -q __fish_git || complete -C"git " &>/dev/null set -l subcommands log show reflog blame grep refs statsh status complete -c tig -n "not contains -- -- (commandline -xpc) && not __fish_seen_subcommand_from $subcommands" -xa 'show\t"Open diff view using the given git-show(1) options" diff --git a/share/completions/yarn.fish b/share/completions/yarn.fish index 0be472f86..dd0aaf536 100644 --- a/share/completions/yarn.fish +++ b/share/completions/yarn.fish @@ -1,6 +1,6 @@ # Yarn 1.22.4 -source $__fish_data_dir/functions/__fish_npm_helper.fish +__fish_npm_helper set -l yarn_add "yarn global add" # Typically there is no need to check if (commandline -ct) begins with `--` diff --git a/share/functions/__fish_npm_helper.fish b/share/functions/__fish_npm_helper.fish index 1e154611a..155d7eb37 100644 --- a/share/functions/__fish_npm_helper.fish +++ b/share/functions/__fish_npm_helper.fish @@ -113,3 +113,7 @@ print("\n".join(data.get("dependencies", []))); print("\n".join(data.get("devDep end end end + +function __fish_npm_helper + # dummy function to allow sourcing this file +end diff --git a/share/functions/__fish_print_help.fish b/share/functions/__fish_print_help.fish index 564aa289c..9b891f78f 100644 --- a/share/functions/__fish_print_help.fish +++ b/share/functions/__fish_print_help.fish @@ -11,7 +11,7 @@ function __fish_print_help --description "Print help message for the specified f end # Do nothing if the file does not exist - if not test -e "$__fish_data_dir/man/man1/$item.1" -o -e "$__fish_data_dir/man/man1/$item.1.gz"; and not status get-file man/man1/$item.1 >/dev/null + if not path is -- $__fish_data_dir/man/man1/$item.1 $__fish_data_dir/man/man1/$item.1.gz; and not status get-file man/man1/$item.1 >/dev/null return 2 end @@ -32,7 +32,7 @@ function __fish_print_help --description "Print help message for the specified f end else if command -qs nroff set format nroff -c -man -t - if test -e $__fish_data_dir/groff/fish.tmac + if path is -- $__fish_data_dir/groff/fish.tmac set -a format -M$__fish_data_dir/groff -mfish end if test -n "$cols" @@ -43,7 +43,7 @@ function __fish_print_help --description "Print help message for the specified f return 1 end - if test -e "$__fish_data_dir/man/man1/$item.1" + if path is -- $__fish_data_dir/man/man1/$item.1 # Some nroff versions screw up non-ascii characters. # (even with the locale set correctly!) # Work around that by running preconv first. @@ -52,7 +52,7 @@ function __fish_print_help --description "Print help message for the specified f else set help ($format "$__fish_data_dir/man/man1/$item.1" 2>/dev/null) end - else if test -e "$__fish_data_dir/man/man1/$item.1.gz" + else if path is -- $__fish_data_dir/man/man1/$item.1.gz if command -sq preconv; and test "$format[1]" = nroff set help (gunzip -c "$__fish_data_dir/man/man1/$item.1.gz" 2>/dev/null | preconv -e UTF-8 | $format 2>/dev/null) else diff --git a/tests/checks/check-all-fish-files.fish b/tests/checks/check-all-fish-files.fish index 7281e7631..bf977528d 100644 --- a/tests/checks/check-all-fish-files.fish +++ b/tests/checks/check-all-fish-files.fish @@ -4,13 +4,14 @@ # Test ALL THE FISH FILES # in share/, that is - the tests are exempt because they contain syntax errors, on purpose +set -l dir (path resolve -- (status dirname)/../../) set timestamp_file ./last_check_all_files set -l find_args if test -f $timestamp_file set find_args -newer $timestamp_file end set -l fail_count 0 -for file in (find $__fish_data_dir/ -name "*.fish" $find_args 2>/dev/null; or find $__fish_data_dir/ -name "*.fish") +for file in (find $dir -name "*.fish" $find_args 2>/dev/null; or find $dir -name "*.fish") $fish -n $file; or set fail_count (math $fail_count + 1) end diff --git a/tests/checks/functions.fish b/tests/checks/functions.fish index f5a17991e..3c1fd15ba 100644 --- a/tests/checks/functions.fish +++ b/tests/checks/functions.fish @@ -30,7 +30,7 @@ functions -D f2 # function that could be autoloaded but isn't currently loaded. set x (functions -D vared) if test (count $x) -ne 1 - or not string match -rq '.*/share(/fish)?/functions/vared\.fish' "$x" + or not string match -rq '.*functions/vared\.fish' "$x" echo "Unexpected output for 'functions -D vared': $x" >&2 end @@ -39,7 +39,7 @@ end # function that was autoloaded. set x (functions -v -D vared) if test (count $x) -ne 5 - or not string match -rq '.*/share(/fish)?/functions/vared\.fish' $x[1] + or not string match -rq '.*functions/vared\.fish' $x[1] or test $x[2] != autoloaded or test $x[3] != 6 or test $x[4] != scope-shadowing diff --git a/tests/checks/no-config.fish b/tests/checks/no-config.fish index 622617d6c..5a3ff241a 100644 --- a/tests/checks/no-config.fish +++ b/tests/checks/no-config.fish @@ -11,6 +11,5 @@ set -S foo # CHECK: $foo: set in global scope, unexported, with 1 elements # CHECK: $foo[1]: |bar| -set -S fish_function_path fish_complete_path -# CHECK: $fish_function_path: set in global scope, unexported, with 1 elements -# CHECK: $fish_function_path[1]: |{{.*}}| +set -q fish_function_path[2] +and echo fish_function_path has two elements diff --git a/tests/checks/type.fish b/tests/checks/type.fish index ea692ccb7..7ad5e4933 100644 --- a/tests/checks/type.fish +++ b/tests/checks/type.fish @@ -37,7 +37,7 @@ type sh # The exact definition and description here depends on the system, so we'll ignore the actual code. type realpath | grep -v "^ *" # CHECK: realpath is a function with definition -# CHECK: # Defined in {{.*}}/functions/realpath.fish @ line {{\d+}} +# CHECK: # Defined in {{.*}}functions/realpath.fish @ line {{\d+}} # CHECK: function realpath --description {{.+}} # CHECK: end