Fix env completions

Previously an environment variable to redefine would only be suggested if you
had not yet started typing one out. This makes it so that `env C<TAB>` will also
complete to, for example, [ `CC=`, `CXXFLAGS=`, ... ].

It also is smarter when suggesting variable names to complete: if a variable has
already been completed, it isn't suggested again. Additionally, it only suggests
names for variables that are exported, not all variables (the previous list was
insanely long and including things like all our `fish_...` variables).
This commit is contained in:
Mahmoud Al-Qudsi 2022-11-09 13:42:19 -06:00
parent 37b0f4dabc
commit add1df12b3

View file

@ -3,6 +3,29 @@ if env --version &>/dev/null
set is_gnu --is-gnu
end
# Returns 0 if we're after `env` and all previous tokens have an equal sign
function __fish_env_defining_vars
not string match -ev -- = (commandline -o)[2..-2] | string match -rq .
end
# Returns 0 if we're after `env` and all previous tokens have not yet contained an equal sign
function __fish_env_not_yet_vars
not string match -qe = (commandline)
end
# Generate a list of possible variable names to redefine, excluding any already redefined.
function __fish_env_redefine_vars
set -l vars (set --names -x)
set cmdline "$(commandline -o)"
for var in $vars
if not string match -e -- $var= $cmdline
echo $var=
end
end
end
# Get the text after all env arguments and variables, so we can complete it as a regular command
function __fish_env_remaining_args -V is_gnu
set -l argv (commandline -opc) (commandline -ct)
if set -q is_gnu[1]
@ -32,6 +55,7 @@ function __fish_env_remaining_args -V is_gnu
test -n "$argv[1]"
end
# Generate a completion for the executable to execute under `env`
function __fish_complete_env_subcommand
if set -l argv (__fish_env_remaining_args)
__fish_complete_subcommand --commandline $argv
@ -39,20 +63,19 @@ function __fish_complete_env_subcommand
end
complete -c env -a "(__fish_complete_env_subcommand)"
complete -c env -n 'not __fish_env_remaining_args; and not string match -eq = -- (commandline -ct)' -a "(set -n)=" -f -d "Redefine variable"
# Complete the name of the variable to redefine
complete -c env -n '__fish_env_defining_vars; and not string match -eq = -- (commandline -ct)' -a "(__fish_env_redefine_vars)" -f -d "Redefine variable"
if set -q is_gnu
# complete VAR= only if the cursor is left of the =, otherwise complete the file right of the =
complete -c env -n 'not __fish_env_remaining_args' -s i -l ignore-environment -d "Start with an empty environment"
complete -c env -n 'not __fish_env_remaining_args' -s u -l unset -d "Unset environment variable" -x -a "(set -n)"
complete -c env -n 'not __fish_env_remaining_args' -l help -d "Display help and exit"
complete -c env -n 'not __fish_env_remaining_args' -l version -d "Display version and exit"
complete -c env -n '__fish_env_not_yet_vars' -s i -l ignore-environment -d "Start with an empty environment"
complete -c env -n '__fish_env_not_yet_vars' -s u -l unset -d "Unset environment variable" -x -a "(set --names -x)"
complete -c env -n '__fish_env_not_yet_vars' -l help -d "Display help and exit"
complete -c env -n '__fish_env_not_yet_vars' -l version -d "Display version and exit"
else
# complete VAR= only if the cursor is left of the =, otherwise complete the file right of the =
complete -c env -n 'not __fish_env_remaining_args' -s 0 -d "End output lines with NUL"
complete -c env -n 'not __fish_env_remaining_args' -s i -d "Start with empty environment"
complete -c env -n 'not __fish_env_remaining_args' -s P -d "Provide an alternate PATH"
complete -c env -n 'not __fish_env_remaining_args' -s S -d "Split argument into args on ' '"
complete -c env -n 'not __fish_env_remaining_args' -s u -d "Unset environment variable" -x -a "(set -n)"
complete -c env -n 'not __fish_env_remaining_args' -s v -d "Verbose output on processing"
complete -c env -n '__fish_env_not_yet_vars' -s 0 -d "End output lines with NUL"
complete -c env -n '__fish_env_not_yet_vars' -s i -d "Start with empty environment"
complete -c env -n '__fish_env_not_yet_vars' -s P -d "Provide an alternate PATH"
complete -c env -n '__fish_env_not_yet_vars' -s S -d "Split argument into args on ' '"
complete -c env -n '__fish_env_not_yet_vars' -s u -d "Unset environment variable" -x -a "(set --names -x)"
complete -c env -n '__fish_env_not_yet_vars' -s v -d "Verbose output on processing"
end