summaryrefslogblamecommitdiff
path: root/share/spack/bash/spack-completion.in
blob: ae9cbc555c6d853ca5416f15c4e80d8c058001ed (plain) (tree)
1
                                                                         





































                                                                               










                                                                            






                                                                                     
                                







































































                                                                                    


                                                                  



































































































                                                                          
                                                    






                                            
                                              












































































                                                                                    






                                                                        


                                          
# Copyright 2013-2021 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
    # ensure base completion support is enabled, ignore insecure directories
    autoload -U +X compinit && compinit -i
    # ensure bash compatible completion support is enabled
    autoload -U +X bashcompinit && bashcompinit
    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}" == " " ]]
    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 [[ "$(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"
}

_tests() {
    if [[ -z "${SPACK_TESTS:-}" ]]
    then
        SPACK_TESTS="$(spack 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.