Implement fish completion (#29549)
* commands: provide more information to Command * fish: Add script to generate fish completion * fish: auto prepend `spack` command to avoid duplication * fish: impove completion generation code readability * commands: replace match-case with if-else * fish: fix optspec variable name prefix * fish: fix return value in get_optspecs * fish: fix return value in get_optspecs * format: split long line and trim trailing space * bugfix: replace f-string with interpolation * fish: compete more specs and some fixes * fish: complete hash spec starts with / * fish: improve compatibility * style: trim trailing whitespace * commands: add fish to update args and update tests * commands: add fish completion file * style: merge imports * fish: source completion in setup-env * fish: caret only completes dependencies * fish: make sure we always get same order of output * fish: spack activate only show installed packages that have extensions * fish: update completion file * fish: make dict keys sorted * Blacken code * Fix bad merge * Undo style changes to setup-env.fish * Fix unit tests * Style fix * Compatible with fish_indent * Use list for stability of order * Sort one more place * Sort more things * Sorting unneeded * Unsort * Print difference * Style fix * Help messages need quotes * Arguments to -a must be quoted * Update types * Update types * Update types * Add type hints * Change order of positionals * Always expand help * Remove shared base class * Fix type hints * Remove platform-specific choices * First line of help only * Remove unused maps * Remove suppress * Remove debugging comments * Better quoting * Fish completions have no double dash * Remove test for deleted class * Fix grammar in header file * Use single quotes in most places * Better support for remainder nargs * No magic strings * * and + can also complete multiple * lower case, no period --------- Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
This commit is contained in:
347
share/spack/fish/spack-completion.in
Normal file
347
share/spack/fish/spack-completion.in
Normal file
@@ -0,0 +1,347 @@
|
||||
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
# NOTE: spack-completion.fish is auto-generated by:
|
||||
#
|
||||
# $ spack commands --aliases --format=fish
|
||||
# --header=fish/spack-completion.in --update=spack-completion.fish
|
||||
#
|
||||
# Please do not manually modify this file.
|
||||
|
||||
# Check fish version before proceeding
|
||||
set -l fish_version (string split '.' $FISH_VERSION)
|
||||
if test $fish_version[1] -lt 3
|
||||
if test $fish_version[1] -eq 3
|
||||
and test $fish_version[2] -lt 2
|
||||
echo 'Fish version is older than 3.2.0. Some completion features may not work'
|
||||
set -g __fish_spack_force_files
|
||||
else
|
||||
echo 'This script requires fish version 3.0 or later'
|
||||
exit 1
|
||||
end
|
||||
else
|
||||
set -g __fish_spack_force_files -F
|
||||
end
|
||||
|
||||
# The following global variables are used as a cache of `__fish_spack_argparse`
|
||||
|
||||
# Cached command line
|
||||
set -g __fish_spack_argparse_cache_line
|
||||
# Parsed command
|
||||
set -g __fish_spack_argparse_command
|
||||
# Remaining arguments
|
||||
set -g __fish_spack_argparse_argv
|
||||
# Return value
|
||||
set -g __fish_spack_argparse_return
|
||||
|
||||
# Spack command generates an optspec variable $__fish_spack_optspecs_<command>.
|
||||
# We check if this command exists, and echo the optspec variable name.
|
||||
function __fish_spack_get_optspecs -d 'Get optspecs of spack command'
|
||||
# Convert arguments to replace ' ' and '-' by '_'
|
||||
set -l cmd_var (string replace -ra -- '[ -]' '_' $argv | string join '_')
|
||||
# Set optspec variable name
|
||||
set -l optspecs_var __fish_spack_optspecs_$cmd_var
|
||||
# Query if variable $$optspecs_var exists
|
||||
set -q $optspecs_var; or return 1
|
||||
# If it exists, echo all optspecs line by line.
|
||||
# String join returns 1 if no join was performed, so we return 0 in such case.
|
||||
string join \n $$optspecs_var; or return 0
|
||||
end
|
||||
|
||||
# Parse command-line arguments, save results to global variables,
|
||||
# and add found flags to __fish_spack_flag_<flag>.
|
||||
# Returns 1 if help flag is found.
|
||||
function __fish_spack_argparse
|
||||
# Figure out if the current invocation already has a command.
|
||||
set -l args $argv
|
||||
set -l commands
|
||||
|
||||
# Return cached result if arguments haven't changed
|
||||
if test "$__fish_spack_argparse_cache_line" = "$args"
|
||||
return $__fish_spack_argparse_return
|
||||
end
|
||||
|
||||
# Clear all flags found in last run
|
||||
set -g | string replace -rf -- '^(__fish_spack_flag_\w+)(.*?)$' 'set -ge $1' | source
|
||||
|
||||
# Set default return value to 0, indicating success
|
||||
set -g __fish_spack_argparse_return 0
|
||||
# Set command line to current arguments
|
||||
set -g __fish_spack_argparse_cache_line $argv
|
||||
|
||||
# Recursively check arguments for commands
|
||||
while set -q args[1]
|
||||
# Get optspecs of current command
|
||||
set -l optspecs (__fish_spack_get_optspecs $commands $args[1])
|
||||
or break
|
||||
|
||||
# If command exists, shift arguments
|
||||
set -a commands $args[1]
|
||||
set -e args[1]
|
||||
|
||||
# If command has no arguments, continue
|
||||
set -q optspecs[1]; or continue
|
||||
|
||||
# Parse arguments. Set variable _flag_<flag> if flag is found.
|
||||
# We find all these variables and set them to the global variable __fish_spack_flag_<flag>.
|
||||
argparse -i -s $optspecs -- $args 2>/dev/null; or break
|
||||
set -l | string replace -rf -- '^(_flag_.*)$' 'set -g __fish_spack$1' | source
|
||||
|
||||
# Set args to not parsed arguments
|
||||
set args $argv
|
||||
|
||||
# If command has help flag, we don't need to parse more so short circuit
|
||||
if set -q _flag_help
|
||||
set -g __fish_spack_argparse_return 1
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Set cached variables
|
||||
set -g __fish_spack_argparse_command $commands
|
||||
set -g __fish_spack_argparse_argv $args
|
||||
|
||||
return $__fish_spack_argparse_return
|
||||
end
|
||||
|
||||
# Check if current commandline's command is "spack $argv"
|
||||
function __fish_spack_using_command
|
||||
set -l line (commandline -opc)
|
||||
__fish_spack_argparse $line; or return 1
|
||||
|
||||
set -p argv spack
|
||||
test "$__fish_spack_argparse_command" = "$argv"
|
||||
end
|
||||
|
||||
# Check if current commandline's command is "spack $argv[2..-1]",
|
||||
# and cursor is at $argv[1]-th positional argument
|
||||
function __fish_spack_using_command_pos
|
||||
__fish_spack_using_command $argv[2..-1]
|
||||
or return
|
||||
|
||||
test (count $__fish_spack_argparse_argv) -eq $argv[1]
|
||||
end
|
||||
|
||||
function __fish_spack_using_command_pos_remainder
|
||||
__fish_spack_using_command $argv[2..-1]
|
||||
or return
|
||||
|
||||
test (count $__fish_spack_argparse_argv) -ge $argv[1]
|
||||
end
|
||||
|
||||
# Helper functions for subcommands
|
||||
|
||||
function __fish_spack_bootstrap_names
|
||||
if set -q __fish_spack_flag_scope
|
||||
spack bootstrap list --scope $__fish_spack_flag_scope | string replace -rf -- '^Name: (\w+).*?$' '$1'
|
||||
else
|
||||
spack bootstrap list | string replace -rf -- '^Name: (\w+).*?$' '$1'
|
||||
end
|
||||
end
|
||||
|
||||
# Reference: sudo's fish completion
|
||||
function __fish_spack_build_env_spec
|
||||
set token (commandline -opt)
|
||||
|
||||
set -l index (contains -- -- $__fish_spack_argparse_argv)
|
||||
if set -q index[1]
|
||||
__fish_complete_subcommand --commandline $__fish_spack_argparse_argv[(math $index + 1)..-1]
|
||||
else if set -q __fish_spack_argparse_argv[1]
|
||||
__fish_complete_subcommand --commandline "$__fish_spack_argparse_argv[2..-1] $token"
|
||||
else
|
||||
__fish_spack_specs
|
||||
end
|
||||
end
|
||||
|
||||
function __fish_spack_commands
|
||||
spack commands
|
||||
end
|
||||
|
||||
function __fish_spack_colon_path
|
||||
set token (string split -rm1 ':' (commandline -opt))
|
||||
|
||||
if test (count $token) -lt 2
|
||||
__fish_complete_path $token[1]
|
||||
else
|
||||
__fish_complete_path $token[2] | string replace -r -- '^' "$token[1]:"
|
||||
end
|
||||
end
|
||||
|
||||
function __fish_spack_config_sections
|
||||
if set -q __fish_spack_flag_scope
|
||||
spack config --scope $__fish_spack_flag_scope list | string split ' '
|
||||
else
|
||||
spack config list | string split ' '
|
||||
end
|
||||
end
|
||||
|
||||
function __fish_spack_environments
|
||||
string trim (spack env list)
|
||||
end
|
||||
|
||||
function __fish_spack_extensions
|
||||
# Skip optional flags, or it will be really slow
|
||||
string match -q -- '-*' (commandline -opt)
|
||||
and return
|
||||
|
||||
comm -1 -2 (spack extensions | string trim | psub) (__fish_spack_installed_packages | sort | psub)
|
||||
end
|
||||
|
||||
function __fish_spack_gpg_keys
|
||||
spack gpg list
|
||||
end
|
||||
|
||||
function __fish_spack_installed_compilers
|
||||
spack compilers | grep -v '^[=-]\|^$'
|
||||
end
|
||||
|
||||
function __fish_spack_installed_packages
|
||||
spack find --no-groups --format '{name}' | uniq
|
||||
end
|
||||
|
||||
function __fish_spack_installed_specs
|
||||
# Try match local hash first
|
||||
__fish_spack_installed_specs_id
|
||||
and return
|
||||
|
||||
spack find --no-groups --format '{name}@{version}'
|
||||
end
|
||||
|
||||
function __fish_spack_installed_specs_id
|
||||
set -l token (commandline -opt)
|
||||
string match -q -- '/*' $token
|
||||
or return 1
|
||||
|
||||
spack find --format '/{hash:7}'\t'{name}{@version}'
|
||||
end
|
||||
|
||||
function __fish_spack_git_rev
|
||||
type -q __fish_git_ranges
|
||||
and __fish_git_ranges
|
||||
end
|
||||
|
||||
function __fish_spack_mirrors
|
||||
spack mirror list | awk {'printf ("%s\t%s", $1, $2)'}
|
||||
end
|
||||
|
||||
function __fish_spack_package_versions
|
||||
string trim (spack versions $argv)
|
||||
end
|
||||
|
||||
function __fish_spack_packages
|
||||
spack list
|
||||
end
|
||||
|
||||
function __fish_spack_pkg_packages
|
||||
spack pkg list
|
||||
end
|
||||
|
||||
function __fish_spack_providers
|
||||
string trim (spack providers | grep -v '^$')
|
||||
end
|
||||
|
||||
function __fish_spack_repos
|
||||
spack repo list | awk {'printf ("%s\t%s", $1, $2)'}
|
||||
end
|
||||
|
||||
function __fish_spack_scopes
|
||||
# TODO: how to list all scopes?
|
||||
set -l scope system site user defaults
|
||||
set -l platform cray darwin linux test
|
||||
|
||||
string join \n $scope
|
||||
end
|
||||
|
||||
function __fish_spack_specs
|
||||
set -l token (commandline -opt)
|
||||
|
||||
# Complete compilers
|
||||
if string match -rq -- '^(?<pre>.*%)[\w-]*(@[\w\.+~-]*)?$' $token
|
||||
__fish_spack_installed_compilers | string replace -r -- '^' "$pre"
|
||||
return
|
||||
end
|
||||
|
||||
# Try to complete spec version
|
||||
# Currently we can only match '@' after a package name
|
||||
set -l package
|
||||
|
||||
# Match ^ following package name
|
||||
if string match -rq -- '^(?<pre>.*?\^)[\w\.+~-]*$' $token
|
||||
# Package name is the nearest, assuming first character is always a letter or digit
|
||||
set packages (string match -ar -- '^[\w-]+' $__fish_spack_argparse_argv $token)
|
||||
set package $packages[-1]
|
||||
|
||||
if test -n "$package"
|
||||
spack dependencies $package | string replace -r -- '^' "$pre"
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Match @ following package name
|
||||
if string match -rq -- '^(?<pre>.*?\^?(?<packages>[\w\.+~-]*)@)[\w\.]*$' $token
|
||||
set package $packages[-1]
|
||||
|
||||
# Matched @ starting at next token
|
||||
if test -z "$package"
|
||||
string match -arq -- '(^|\^)(?<inners>[\w\.+~-]*)$' $__fish_spack_argparse_argv[-1]
|
||||
if test -n "$inners[1]"
|
||||
set package $inners[-1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Complete version if package found
|
||||
if test -n "$package"
|
||||
# Only list safe versions for speed
|
||||
string trim (spack versions --safe $package) | string replace -r -- '^' "$pre"
|
||||
return
|
||||
end
|
||||
|
||||
# Else complete package name
|
||||
__fish_spack_installed_packages | string replace -r -- '$' \t"installed"
|
||||
spack list
|
||||
end
|
||||
|
||||
function __fish_spack_specs_or_id
|
||||
# Try to match local hash first
|
||||
__fish_spack_installed_specs_id
|
||||
and return
|
||||
|
||||
__fish_spack_specs
|
||||
end
|
||||
|
||||
function __fish_spack_tags
|
||||
string trim (spack tags)
|
||||
end
|
||||
|
||||
function __fish_spack_tests
|
||||
spack test list | grep -v '^[=-]'
|
||||
end
|
||||
|
||||
function __fish_spack_unit_tests
|
||||
# Skip optional flags, or it will be really slow
|
||||
string match -q -- '-*' (commandline -opt)
|
||||
and return
|
||||
|
||||
spack unit-test -l
|
||||
end
|
||||
|
||||
function __fish_spack_yamls
|
||||
# Trim flag from current token
|
||||
string match -rq -- '(?<pre>-.)?(?<token>.*)' (commandline -opt)
|
||||
|
||||
if test -n "$token"
|
||||
find $token* -type f '(' -iname '*.yaml' -or -iname '*.yml' ')'
|
||||
else
|
||||
find -maxdepth 2 -type f '(' -iname '*.yaml' -or -iname '*.yml' ')' | cut -c 3-
|
||||
end
|
||||
end
|
||||
|
||||
# Reset existing completions
|
||||
complete -c spack --erase
|
||||
|
||||
# Spack commands
|
||||
#
|
||||
# Everything below here is auto-generated.
|
Reference in New Issue
Block a user