From 39d4c402d568c520377378e4246c198f2f07de06 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Wed, 9 Aug 2023 08:28:55 -0500 Subject: Fix suffix of tab completion scripts (#39154) --- lib/spack/spack/cmd/commands.py | 4 +- lib/spack/spack/test/cmd/commands.py | 5 +- share/spack/bash/spack-completion.bash | 333 +++++++++++++++++++++++++++++++ share/spack/bash/spack-completion.in | 333 ------------------------------- share/spack/fish/spack-completion.fish | 347 +++++++++++++++++++++++++++++++++ share/spack/fish/spack-completion.in | 347 --------------------------------- share/spack/spack-completion.bash | 2 +- share/spack/spack-completion.fish | 2 +- 8 files changed, 687 insertions(+), 686 deletions(-) create mode 100755 share/spack/bash/spack-completion.bash delete mode 100755 share/spack/bash/spack-completion.in create mode 100644 share/spack/fish/spack-completion.fish delete mode 100644 share/spack/fish/spack-completion.in diff --git a/lib/spack/spack/cmd/commands.py b/lib/spack/spack/cmd/commands.py index a65031387d..61be25f036 100644 --- a/lib/spack/spack/cmd/commands.py +++ b/lib/spack/spack/cmd/commands.py @@ -36,13 +36,13 @@ update_completion_args: Dict[str, Dict[str, Any]] = { "bash": { "aliases": True, "format": "bash", - "header": os.path.join(spack.paths.share_path, "bash", "spack-completion.in"), + "header": os.path.join(spack.paths.share_path, "bash", "spack-completion.bash"), "update": os.path.join(spack.paths.share_path, "spack-completion.bash"), }, "fish": { "aliases": True, "format": "fish", - "header": os.path.join(spack.paths.share_path, "fish", "spack-completion.in"), + "header": os.path.join(spack.paths.share_path, "fish", "spack-completion.fish"), "update": os.path.join(spack.paths.share_path, "spack-completion.fish"), }, } diff --git a/lib/spack/spack/test/cmd/commands.py b/lib/spack/spack/test/cmd/commands.py index 7a531b4f91..5bd0e20e60 100644 --- a/lib/spack/spack/test/cmd/commands.py +++ b/lib/spack/spack/test/cmd/commands.py @@ -219,7 +219,8 @@ def test_fish_completion(): def test_update_completion_arg(shell, tmpdir, monkeypatch): """Test the update completion flag.""" - mock_infile = tmpdir.join("spack-completion.in") + tmpdir.join(shell).mkdir() + mock_infile = tmpdir.join(shell).join(f"spack-completion.{shell}") mock_outfile = tmpdir.join(f"spack-completion.{shell}") mock_args = { @@ -267,7 +268,7 @@ def test_updated_completion_scripts(shell, tmpdir): "and adding the changed files to your pull request." ) - header = os.path.join(spack.paths.share_path, shell, "spack-completion.in") + header = os.path.join(spack.paths.share_path, shell, f"spack-completion.{shell}") script = "spack-completion.{0}".format(shell) old_script = os.path.join(spack.paths.share_path, script) new_script = str(tmpdir.join(script)) diff --git a/share/spack/bash/spack-completion.bash b/share/spack/bash/spack-completion.bash new file mode 100755 index 0000000000..0d740101fa --- /dev/null +++ b/share/spack/bash/spack-completion.bash @@ -0,0 +1,333 @@ +# 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.bash is auto-generated by: +# +# $ spack commands --aliases --format=bash +# --header=bash/spack-completion.bash --update=spack-completion.bash +# +# Please do not manually modify this file. + + +# The following global variables are set by Bash programmable completion: +# +# COMP_CWORD: An index into ${COMP_WORDS} of the word containing the +# current cursor position +# COMP_KEY: The key (or final key of a key sequence) used to invoke +# the current completion function +# COMP_LINE: The current command line +# COMP_POINT: The index of the current cursor position relative to the +# beginning of the current command +# COMP_TYPE: Set to an integer value corresponding to the type of +# completion attempted that caused a completion function +# to be called +# COMP_WORDBREAKS: The set of characters that the readline library treats +# as word separators when performing word completion +# COMP_WORDS: An array variable consisting of the individual words in +# the current command line +# +# The following global variable is used by Bash programmable completion: +# +# COMPREPLY: An array variable from which bash reads the possible +# completions generated by a shell function invoked by the +# programmable completion facility +# +# See `man bash` for more details. + +if test -n "${ZSH_VERSION:-}" ; then + if [[ "$(emulate)" = zsh ]] ; then + if ! typeset -f compdef >& /dev/null ; then + # ensure base completion support is enabled, ignore insecure directories + autoload -U +X compinit && compinit -i + fi + if ! typeset -f complete >& /dev/null ; then + # ensure bash compatible completion support is enabled + autoload -U +X bashcompinit && bashcompinit + fi + emulate sh -c "source '$0:A'" + return # stop interpreting file + fi +fi + +# Bash programmable completion for Spack +_bash_completion_spack() { + # In all following examples, let the cursor be denoted by brackets, i.e. [] + + # For our purposes, flags should not affect tab completion. For instance, + # `spack install []` and `spack -d install --jobs 8 []` should both give the same + # possible completions. Therefore, we need to ignore any flags in COMP_WORDS. + local -a COMP_WORDS_NO_FLAGS + local index=0 + while [[ "$index" -lt "$COMP_CWORD" ]] + do + if [[ "${COMP_WORDS[$index]}" == [a-z]* ]] + then + COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$index]}") + fi + let index++ + done + + # Options will be listed by a subfunction named after non-flag arguments. + # For example, `spack -d install []` will call _spack_install + # and `spack compiler add []` will call _spack_compiler_add + local subfunction=$(IFS='_'; echo "_${COMP_WORDS_NO_FLAGS[*]}") + + # Translate dashes to underscores, as dashes are not permitted in + # compatibility mode. See https://github.com/spack/spack/pull/4079 + subfunction=${subfunction//-/_} + + # However, the word containing the current cursor position needs to be + # added regardless of whether or not it is a flag. This allows us to + # complete something like `spack install --keep-st[]` + COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$COMP_CWORD]}") + + # Since we have removed all words after COMP_CWORD, we can safely assume + # that COMP_CWORD_NO_FLAGS is simply the index of the last element + local COMP_CWORD_NO_FLAGS=$((${#COMP_WORDS_NO_FLAGS[@]} - 1)) + + # There is no guarantee that the cursor is at the end of the command line + # when tab completion is envoked. For example, in the following situation: + # `spack -d [] install` + # if the user presses the TAB key, a list of valid flags should be listed. + # Note that we cannot simply ignore everything after the cursor. In the + # previous scenario, the user should expect to see a list of flags, but + # not of other subcommands. Obviously, `spack -d list install` would be + # invalid syntax. To accomplish this, we use the variable list_options + # which is true if the current word starts with '-' or if the cursor is + # not at the end of the line. + local list_options=false + if [[ "${COMP_WORDS[$COMP_CWORD]}" == -* || "$COMP_POINT" -ne "${#COMP_LINE}" ]] + then + list_options=true + fi + + # In general, when envoking tab completion, the user is not expecting to + # see optional flags mixed in with subcommands or package names. Tab + # completion is used by those who are either lazy or just bad at spelling. + # If someone doesn't remember what flag to use, seeing single letter flags + # in their results won't help them, and they should instead consult the + # documentation. However, if the user explicitly declares that they are + # looking for a flag, we can certainly help them out. + # `spack install -[]` + # and + # `spack install --[]` + # should list all flags and long flags, respectively. Furthermore, if a + # subcommand has no non-flag completions, such as `spack arch []`, it + # should list flag completions. + + local cur=${COMP_WORDS_NO_FLAGS[$COMP_CWORD_NO_FLAGS]} + + # If the cursor is in the middle of the line, like: + # `spack -d [] install` + # COMP_WORDS will not contain the empty character, so we have to add it. + if [[ "${COMP_LINE:$COMP_POINT-1:1}" == " " ]] + then + cur="" + fi + + # Uncomment this line to enable logging + #_test_vars >> temp + + # Make sure function exists before calling it + local rgx #this dance is necessary to cover bash and zsh regex + rgx="$subfunction.*function.* " + if [[ "$(LC_ALL=C type $subfunction 2>&1)" =~ $rgx ]] + then + $subfunction + COMPREPLY=($(compgen -W "$SPACK_COMPREPLY" -- "$cur")) + fi +} + +# Helper functions for subcommands +# Results of each query are cached via environment variables + +_subcommands() { + if [[ -z "${SPACK_SUBCOMMANDS:-}" ]] + then + SPACK_SUBCOMMANDS="$(spack commands)" + fi + SPACK_COMPREPLY="$SPACK_SUBCOMMANDS" +} + +_all_packages() { + if [[ -z "${SPACK_ALL_PACKAGES:-}" ]] + then + SPACK_ALL_PACKAGES="$(spack list)" + fi + SPACK_COMPREPLY="$SPACK_ALL_PACKAGES" +} + +_all_resource_hashes() { + if [[ -z "${SPACK_ALL_RESOURCES_HASHES:-}" ]] + then + SPACK_ALL_RESOURCE_HASHES="$(spack resource list --only-hashes)" + fi + SPACK_COMPREPLY="$SPACK_ALL_RESOURCE_HASHES" +} + +_installed_packages() { + if [[ -z "${SPACK_INSTALLED_PACKAGES:-}" ]] + then + SPACK_INSTALLED_PACKAGES="$(spack --color=never find --no-groups)" + fi + SPACK_COMPREPLY="$SPACK_INSTALLED_PACKAGES" +} + +_installed_compilers() { + if [[ -z "${SPACK_INSTALLED_COMPILERS:-}" ]] + then + SPACK_INSTALLED_COMPILERS="$(spack compilers | egrep -v "^(-|=)")" + fi + SPACK_COMPREPLY="$SPACK_INSTALLED_COMPILERS" +} + +_providers() { + if [[ -z "${SPACK_PROVIDERS:-}" ]] + then + SPACK_PROVIDERS="$(spack providers)" + fi + SPACK_COMPREPLY="$SPACK_PROVIDERS" +} + +_mirrors() { + if [[ -z "${SPACK_MIRRORS:-}" ]] + then + SPACK_MIRRORS="$(spack mirror list | awk '{print $1}')" + fi + SPACK_COMPREPLY="$SPACK_MIRRORS" +} + +_repos() { + if [[ -z "${SPACK_REPOS:-}" ]] + then + SPACK_REPOS="$(spack repo list | awk '{print $1}')" + fi + SPACK_COMPREPLY="$SPACK_REPOS" +} + +_unit_tests() { + if [[ -z "${SPACK_TESTS:-}" ]] + then + SPACK_TESTS="$(spack unit-test -l)" + fi + SPACK_COMPREPLY="$SPACK_TESTS" +} + +_environments() { + if [[ -z "${SPACK_ENVIRONMENTS:-}" ]] + then + SPACK_ENVIRONMENTS="$(spack env list)" + fi + SPACK_COMPREPLY="$SPACK_ENVIRONMENTS" +} + +_keys() { + if [[ -z "${SPACK_KEYS:-}" ]] + then + SPACK_KEYS="$(spack gpg list)" + fi + SPACK_COMPREPLY="$SPACK_KEYS" +} + +_config_sections() { + if [[ -z "${SPACK_CONFIG_SECTIONS:-}" ]] + then + SPACK_CONFIG_SECTIONS="$(spack config list)" + fi + SPACK_COMPREPLY="$SPACK_CONFIG_SECTIONS" +} + +_extensions() { + if [[ -z "${SPACK_EXTENSIONS:-}" ]] + then + SPACK_EXTENSIONS="$(spack extensions)" + fi + SPACK_COMPREPLY="$SPACK_EXTENSIONS" +} + +# Testing functions + +# Function for unit testing tab completion +# Syntax: _spack_completions spack install py- +_spack_completions() { + local COMP_CWORD COMP_KEY COMP_LINE COMP_POINT COMP_TYPE COMP_WORDS COMPREPLY + + # Set each variable the way bash would + COMP_LINE="$*" + COMP_POINT=${#COMP_LINE} + COMP_WORDS=("$@") + if [[ ${COMP_LINE: -1} == ' ' ]] + then + COMP_WORDS+=('') + fi + COMP_CWORD=$((${#COMP_WORDS[@]} - 1)) + COMP_KEY=9 # ASCII 09: Horizontal Tab + COMP_TYPE=64 # ASCII 64: '@', to list completions if the word is not unmodified + + # Run Spack's tab completion function + _bash_completion_spack + + # Return the result + echo "${COMPREPLY[@]:-}" +} + +# Log the environment variables used +# Syntax: _test_vars >> temp +_test_vars() { + echo "-----------------------------------------------------" + echo "Variables set by bash:" + echo + echo "COMP_LINE: '$COMP_LINE'" + echo "# COMP_LINE: '${#COMP_LINE}'" + echo "COMP_WORDS: $(_pretty_print COMP_WORDS[@])" + echo "# COMP_WORDS: '${#COMP_WORDS[@]}'" + echo "COMP_CWORD: '$COMP_CWORD'" + echo "COMP_KEY: '$COMP_KEY'" + echo "COMP_POINT: '$COMP_POINT'" + echo "COMP_TYPE: '$COMP_TYPE'" + echo "COMP_WORDBREAKS: '$COMP_WORDBREAKS'" + echo + echo "Intermediate variables:" + echo + echo "COMP_WORDS_NO_FLAGS: $(_pretty_print COMP_WORDS_NO_FLAGS[@])" + echo "# COMP_WORDS_NO_FLAGS: '${#COMP_WORDS_NO_FLAGS[@]}'" + echo "COMP_CWORD_NO_FLAGS: '$COMP_CWORD_NO_FLAGS'" + echo + echo "Subfunction: '$subfunction'" + if $list_options + then + echo "List options: 'True'" + else + echo "List options: 'False'" + fi + echo "Current word: '$cur'" +} + +# Pretty-prints one or more arrays +# Syntax: _pretty_print array1[@] ... +_pretty_print() { + for arg in $@ + do + local array=("${!arg}") + printf "$arg: [" + printf "'%s'" "${array[0]}" + printf ", '%s'" "${array[@]:1}" + echo "]" + done +} + +complete -o bashdefault -o default -F _bash_completion_spack spack + +# Completion for spacktivate +complete -o bashdefault -o default -F _bash_completion_spack spacktivate + +_spacktivate() { + _spack_env_activate +} + +# Spack commands +# +# Everything below here is auto-generated. diff --git a/share/spack/bash/spack-completion.in b/share/spack/bash/spack-completion.in deleted file mode 100755 index 048c865649..0000000000 --- a/share/spack/bash/spack-completion.in +++ /dev/null @@ -1,333 +0,0 @@ -# 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.bash is auto-generated by: -# -# $ spack commands --aliases --format=bash -# --header=bash/spack-completion.in --update=spack-completion.bash -# -# Please do not manually modify this file. - - -# The following global variables are set by Bash programmable completion: -# -# COMP_CWORD: An index into ${COMP_WORDS} of the word containing the -# current cursor position -# COMP_KEY: The key (or final key of a key sequence) used to invoke -# the current completion function -# COMP_LINE: The current command line -# COMP_POINT: The index of the current cursor position relative to the -# beginning of the current command -# COMP_TYPE: Set to an integer value corresponding to the type of -# completion attempted that caused a completion function -# to be called -# COMP_WORDBREAKS: The set of characters that the readline library treats -# as word separators when performing word completion -# COMP_WORDS: An array variable consisting of the individual words in -# the current command line -# -# The following global variable is used by Bash programmable completion: -# -# COMPREPLY: An array variable from which bash reads the possible -# completions generated by a shell function invoked by the -# programmable completion facility -# -# See `man bash` for more details. - -if test -n "${ZSH_VERSION:-}" ; then - if [[ "$(emulate)" = zsh ]] ; then - if ! typeset -f compdef >& /dev/null ; then - # ensure base completion support is enabled, ignore insecure directories - autoload -U +X compinit && compinit -i - fi - if ! typeset -f complete >& /dev/null ; then - # ensure bash compatible completion support is enabled - autoload -U +X bashcompinit && bashcompinit - fi - emulate sh -c "source '$0:A'" - return # stop interpreting file - fi -fi - -# Bash programmable completion for Spack -_bash_completion_spack() { - # In all following examples, let the cursor be denoted by brackets, i.e. [] - - # For our purposes, flags should not affect tab completion. For instance, - # `spack install []` and `spack -d install --jobs 8 []` should both give the same - # possible completions. Therefore, we need to ignore any flags in COMP_WORDS. - local -a COMP_WORDS_NO_FLAGS - local index=0 - while [[ "$index" -lt "$COMP_CWORD" ]] - do - if [[ "${COMP_WORDS[$index]}" == [a-z]* ]] - then - COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$index]}") - fi - let index++ - done - - # Options will be listed by a subfunction named after non-flag arguments. - # For example, `spack -d install []` will call _spack_install - # and `spack compiler add []` will call _spack_compiler_add - local subfunction=$(IFS='_'; echo "_${COMP_WORDS_NO_FLAGS[*]}") - - # Translate dashes to underscores, as dashes are not permitted in - # compatibility mode. See https://github.com/spack/spack/pull/4079 - subfunction=${subfunction//-/_} - - # However, the word containing the current cursor position needs to be - # added regardless of whether or not it is a flag. This allows us to - # complete something like `spack install --keep-st[]` - COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$COMP_CWORD]}") - - # Since we have removed all words after COMP_CWORD, we can safely assume - # that COMP_CWORD_NO_FLAGS is simply the index of the last element - local COMP_CWORD_NO_FLAGS=$((${#COMP_WORDS_NO_FLAGS[@]} - 1)) - - # There is no guarantee that the cursor is at the end of the command line - # when tab completion is envoked. For example, in the following situation: - # `spack -d [] install` - # if the user presses the TAB key, a list of valid flags should be listed. - # Note that we cannot simply ignore everything after the cursor. In the - # previous scenario, the user should expect to see a list of flags, but - # not of other subcommands. Obviously, `spack -d list install` would be - # invalid syntax. To accomplish this, we use the variable list_options - # which is true if the current word starts with '-' or if the cursor is - # not at the end of the line. - local list_options=false - if [[ "${COMP_WORDS[$COMP_CWORD]}" == -* || "$COMP_POINT" -ne "${#COMP_LINE}" ]] - then - list_options=true - fi - - # In general, when envoking tab completion, the user is not expecting to - # see optional flags mixed in with subcommands or package names. Tab - # completion is used by those who are either lazy or just bad at spelling. - # If someone doesn't remember what flag to use, seeing single letter flags - # in their results won't help them, and they should instead consult the - # documentation. However, if the user explicitly declares that they are - # looking for a flag, we can certainly help them out. - # `spack install -[]` - # and - # `spack install --[]` - # should list all flags and long flags, respectively. Furthermore, if a - # subcommand has no non-flag completions, such as `spack arch []`, it - # should list flag completions. - - local cur=${COMP_WORDS_NO_FLAGS[$COMP_CWORD_NO_FLAGS]} - - # If the cursor is in the middle of the line, like: - # `spack -d [] install` - # COMP_WORDS will not contain the empty character, so we have to add it. - if [[ "${COMP_LINE:$COMP_POINT-1:1}" == " " ]] - then - cur="" - fi - - # Uncomment this line to enable logging - #_test_vars >> temp - - # Make sure function exists before calling it - local rgx #this dance is necessary to cover bash and zsh regex - rgx="$subfunction.*function.* " - if [[ "$(LC_ALL=C type $subfunction 2>&1)" =~ $rgx ]] - then - $subfunction - COMPREPLY=($(compgen -W "$SPACK_COMPREPLY" -- "$cur")) - fi -} - -# Helper functions for subcommands -# Results of each query are cached via environment variables - -_subcommands() { - if [[ -z "${SPACK_SUBCOMMANDS:-}" ]] - then - SPACK_SUBCOMMANDS="$(spack commands)" - fi - SPACK_COMPREPLY="$SPACK_SUBCOMMANDS" -} - -_all_packages() { - if [[ -z "${SPACK_ALL_PACKAGES:-}" ]] - then - SPACK_ALL_PACKAGES="$(spack list)" - fi - SPACK_COMPREPLY="$SPACK_ALL_PACKAGES" -} - -_all_resource_hashes() { - if [[ -z "${SPACK_ALL_RESOURCES_HASHES:-}" ]] - then - SPACK_ALL_RESOURCE_HASHES="$(spack resource list --only-hashes)" - fi - SPACK_COMPREPLY="$SPACK_ALL_RESOURCE_HASHES" -} - -_installed_packages() { - if [[ -z "${SPACK_INSTALLED_PACKAGES:-}" ]] - then - SPACK_INSTALLED_PACKAGES="$(spack --color=never find --no-groups)" - fi - SPACK_COMPREPLY="$SPACK_INSTALLED_PACKAGES" -} - -_installed_compilers() { - if [[ -z "${SPACK_INSTALLED_COMPILERS:-}" ]] - then - SPACK_INSTALLED_COMPILERS="$(spack compilers | egrep -v "^(-|=)")" - fi - SPACK_COMPREPLY="$SPACK_INSTALLED_COMPILERS" -} - -_providers() { - if [[ -z "${SPACK_PROVIDERS:-}" ]] - then - SPACK_PROVIDERS="$(spack providers)" - fi - SPACK_COMPREPLY="$SPACK_PROVIDERS" -} - -_mirrors() { - if [[ -z "${SPACK_MIRRORS:-}" ]] - then - SPACK_MIRRORS="$(spack mirror list | awk '{print $1}')" - fi - SPACK_COMPREPLY="$SPACK_MIRRORS" -} - -_repos() { - if [[ -z "${SPACK_REPOS:-}" ]] - then - SPACK_REPOS="$(spack repo list | awk '{print $1}')" - fi - SPACK_COMPREPLY="$SPACK_REPOS" -} - -_unit_tests() { - if [[ -z "${SPACK_TESTS:-}" ]] - then - SPACK_TESTS="$(spack unit-test -l)" - fi - SPACK_COMPREPLY="$SPACK_TESTS" -} - -_environments() { - if [[ -z "${SPACK_ENVIRONMENTS:-}" ]] - then - SPACK_ENVIRONMENTS="$(spack env list)" - fi - SPACK_COMPREPLY="$SPACK_ENVIRONMENTS" -} - -_keys() { - if [[ -z "${SPACK_KEYS:-}" ]] - then - SPACK_KEYS="$(spack gpg list)" - fi - SPACK_COMPREPLY="$SPACK_KEYS" -} - -_config_sections() { - if [[ -z "${SPACK_CONFIG_SECTIONS:-}" ]] - then - SPACK_CONFIG_SECTIONS="$(spack config list)" - fi - SPACK_COMPREPLY="$SPACK_CONFIG_SECTIONS" -} - -_extensions() { - if [[ -z "${SPACK_EXTENSIONS:-}" ]] - then - SPACK_EXTENSIONS="$(spack extensions)" - fi - SPACK_COMPREPLY="$SPACK_EXTENSIONS" -} - -# Testing functions - -# Function for unit testing tab completion -# Syntax: _spack_completions spack install py- -_spack_completions() { - local COMP_CWORD COMP_KEY COMP_LINE COMP_POINT COMP_TYPE COMP_WORDS COMPREPLY - - # Set each variable the way bash would - COMP_LINE="$*" - COMP_POINT=${#COMP_LINE} - COMP_WORDS=("$@") - if [[ ${COMP_LINE: -1} == ' ' ]] - then - COMP_WORDS+=('') - fi - COMP_CWORD=$((${#COMP_WORDS[@]} - 1)) - COMP_KEY=9 # ASCII 09: Horizontal Tab - COMP_TYPE=64 # ASCII 64: '@', to list completions if the word is not unmodified - - # Run Spack's tab completion function - _bash_completion_spack - - # Return the result - echo "${COMPREPLY[@]:-}" -} - -# Log the environment variables used -# Syntax: _test_vars >> temp -_test_vars() { - echo "-----------------------------------------------------" - echo "Variables set by bash:" - echo - echo "COMP_LINE: '$COMP_LINE'" - echo "# COMP_LINE: '${#COMP_LINE}'" - echo "COMP_WORDS: $(_pretty_print COMP_WORDS[@])" - echo "# COMP_WORDS: '${#COMP_WORDS[@]}'" - echo "COMP_CWORD: '$COMP_CWORD'" - echo "COMP_KEY: '$COMP_KEY'" - echo "COMP_POINT: '$COMP_POINT'" - echo "COMP_TYPE: '$COMP_TYPE'" - echo "COMP_WORDBREAKS: '$COMP_WORDBREAKS'" - echo - echo "Intermediate variables:" - echo - echo "COMP_WORDS_NO_FLAGS: $(_pretty_print COMP_WORDS_NO_FLAGS[@])" - echo "# COMP_WORDS_NO_FLAGS: '${#COMP_WORDS_NO_FLAGS[@]}'" - echo "COMP_CWORD_NO_FLAGS: '$COMP_CWORD_NO_FLAGS'" - echo - echo "Subfunction: '$subfunction'" - if $list_options - then - echo "List options: 'True'" - else - echo "List options: 'False'" - fi - echo "Current word: '$cur'" -} - -# Pretty-prints one or more arrays -# Syntax: _pretty_print array1[@] ... -_pretty_print() { - for arg in $@ - do - local array=("${!arg}") - printf "$arg: [" - printf "'%s'" "${array[0]}" - printf ", '%s'" "${array[@]:1}" - echo "]" - done -} - -complete -o bashdefault -o default -F _bash_completion_spack spack - -# Completion for spacktivate -complete -o bashdefault -o default -F _bash_completion_spack spacktivate - -_spacktivate() { - _spack_env_activate -} - -# Spack commands -# -# Everything below here is auto-generated. diff --git a/share/spack/fish/spack-completion.fish b/share/spack/fish/spack-completion.fish new file mode 100644 index 0000000000..ee06dade57 --- /dev/null +++ b/share/spack/fish/spack-completion.fish @@ -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.fish --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_. +# 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_. +# 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_ if flag is found. + # We find all these variables and set them to the global variable __fish_spack_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 -- '^(?
.*%)[\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 -- '^(?
.*?\^)[\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 -- '^(?
.*?\^?(?[\w\.+~-]*)@)[\w\.]*$' $token
+        set package $packages[-1]
+
+        # Matched @ starting at next token
+        if test -z "$package"
+            string match -arq -- '(^|\^)(?[\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 -- '(?
-.)?(?.*)' (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.
diff --git a/share/spack/fish/spack-completion.in b/share/spack/fish/spack-completion.in
deleted file mode 100644
index f08c8b1f11..0000000000
--- a/share/spack/fish/spack-completion.in
+++ /dev/null
@@ -1,347 +0,0 @@
-# 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_.
-# 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_.
-# 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_ if flag is found.
-        # We find all these variables and set them to the global variable __fish_spack_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 -- '^(?
.*%)[\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 -- '^(?
.*?\^)[\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 -- '^(?
.*?\^?(?[\w\.+~-]*)@)[\w\.]*$' $token
-        set package $packages[-1]
-
-        # Matched @ starting at next token
-        if test -z "$package"
-            string match -arq -- '(^|\^)(?[\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 -- '(?
-.)?(?.*)' (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.
diff --git a/share/spack/spack-completion.bash b/share/spack/spack-completion.bash
index 9e184aa9a7..f504bea390 100755
--- a/share/spack/spack-completion.bash
+++ b/share/spack/spack-completion.bash
@@ -7,7 +7,7 @@
 # NOTE: spack-completion.bash is auto-generated by:
 #
 #   $ spack commands --aliases --format=bash
-#       --header=bash/spack-completion.in --update=spack-completion.bash
+#       --header=bash/spack-completion.bash --update=spack-completion.bash
 #
 # Please do not manually modify this file.
 
diff --git a/share/spack/spack-completion.fish b/share/spack/spack-completion.fish
index 9b4027dfe3..d743cf0f52 100755
--- a/share/spack/spack-completion.fish
+++ b/share/spack/spack-completion.fish
@@ -6,7 +6,7 @@
 # NOTE: spack-completion.fish is auto-generated by:
 #
 #   $ spack commands --aliases --format=fish
-#       --header=fish/spack-completion.in --update=spack-completion.fish
+#       --header=fish/spack-completion.fish --update=spack-completion.fish
 #
 # Please do not manually modify this file.
 
-- 
cgit v1.2.3-60-g2f50