diff --git a/share/completions/env.fish b/share/completions/env.fish index 1d9d45381..0e8721ee8 100644 --- a/share/completions/env.fish +++ b/share/completions/env.fish @@ -25,6 +25,35 @@ function __fish_env_redefine_vars end end +# Generate a list of possible variable names to define from completion history +function __fish_env_names_from_history + set -l token (commandline -ct) + # Since this is always going to be a best-effort kind of thing, limit this to uppercased variables by convention. + # This prevents us from having to parse quotes to figure out what was part of the payload and what wasn't. + for var in (history search --prefix "env " | string match -ra '\b([A-Z0-9_]+)=' --groups-only) + echo $var= + end +end + +# Generate a list of possible completions for the current variable name from history +function __fish_env_values_from_history + string match -rq "(?.+)=(?.*)" (commandline -ct); or return 1 + + # Caveat lector: very crude multi-word tokenization handling below! + set -l rname (string escape --style=regex -- $name) + set -l search (string trim -c \'\" "$value") + set -l rsearch "$(string escape --style=regex -- $search)" + # Search multi-word values with quotes + set -l query '.*\b'$name'=([\'"])('$rsearch'.+?)\1.*' + set -l matches (history search --prefix "env " | string replace -rfa $query '$2') + # Search multi-word values without quotes + set -l query '.*\b'$name'=('$rsearch'[^\'" ]+).*' + set -a matches (history search --prefix "env " | string replace -rfa $query '$1') + # Display results without quotes + set matches (printf "%s\n" $matches | sort -u) + printf "$name=%s\n" $matches +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) @@ -65,6 +94,8 @@ end complete -c env -a "(__fish_complete_env_subcommand)" # 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" +complete -c env -n '__fish_env_defining_vars; and not string match -eq = -- (commandline -ct)' -a "(__fish_env_names_from_history)" -f -d "Historical" +complete -c env -n '__fish_env_defining_vars; and string match -eq = -- (commandline -ct)' -a "(__fish_env_values_from_history)" -f if set -q is_gnu complete -c env -n '__fish_env_not_yet_vars' -s i -l ignore-environment -d "Start with an empty environment"