share/ramble/bash/ramble-completion.in (223 lines of code) (raw):

# Copyright 2022-2025 The Ramble Authors # # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or # https://www.apache.org/licenses/LICENSE-2.0> or the MIT license # <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your # option. This file may not be copied, modified, or distributed # except according to those terms. # NOTE: ramble-completion.bash is auto-generated by: # # $ ramble commands --update-completion # # 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. # Bash programmable completion for Ramble _bash_completion_ramble() { # In all following examples, let the cursor be denoted by brackets, i.e. [] # For our purposes, flags should not affect tab completion. For instance, # `ramble install []` and `ramble -d install --jobs 8 []` should both give the same # possible completions. Therefore, we need to ignore any flags in COMP_WORDS. local 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, `ramble -d install []` will call _ramble_install # and `ramble compiler add []` will call _ramble_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/ramble/ramble/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 `ramble 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 invoked. For example, in the following situation: # `ramble -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, `ramble -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 evoking 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. # `ramble install -[]` # and # `ramble install --[]` # should list all flags and long flags, respectively. Furthermore, if a # subcommand has no non-flag completions, such as `ramble 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: # `ramble -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 if [[ "$(type -t $subfunction)" == "function" ]] then $subfunction COMPREPLY=($(compgen -W "$RAMBLE_COMPREPLY" -- "$cur")) fi } # Helper functions for subcommands # Results of each query are cached via environment variables _subcommands() { if [[ -z "${RAMBLE_SUBCOMMANDS:-}" ]] then RAMBLE_SUBCOMMANDS="$(ramble commands)" fi RAMBLE_COMPREPLY="$RAMBLE_SUBCOMMANDS" } _all_applications() { if [[ -z "${RAMBLE_ALL_APPLICATIONS:-}" ]] then RAMBLE_ALL_APPLICATIONS="$(ramble list)" fi RAMBLE_COMPREPLY="$RAMBLE_ALL_APPLICATIONS" } _repos() { if [[ -z "${RAMBLE_REPOS:-}" ]] then RAMBLE_REPOS="$(ramble repo list | awk '{print $1}')" fi RAMBLE_COMPREPLY="$RAMBLE_REPOS" } _workspaces() { if [[ -z "${RAMBLE_WORKSPACES:-}" ]] then RAMBLE_WORKSPACES="$(ramble workspace list)" fi RAMBLE_COMPREPLY="$RAMBLE_WORKSPACES" } _tests() { if [[ -z "${RAMBLE_TESTS:-}" ]] then RAMBLE_TESTS="$(ramble test -l)" fi RAMBLE_COMPREPLY="$RAMBLE_TESTS" } _config_sections() { if [[ -z "${RAMBLE_CONFIG_SECTIONS:-}" ]] then RAMBLE_CONFIG_SECTIONS="$(ramble config list)" fi RAMBLE_COMPREPLY="$RAMBLE_CONFIG_SECTIONS" } _extensions() { if [[ -z "${RAMBLE_EXTENSIONS:-}" ]] then RAMBLE_EXTENSIONS="$(ramble extensions)" fi RAMBLE_COMPREPLY="$RAMBLE_EXTENSIONS" } # Testing functions # Function for unit testing tab completion # Syntax: _ramble_completions ramble install py- _ramble_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 Ramble's tab completion function _bash_completion_ramble # 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_ramble ramble # Ramble commands # # Everything below here is auto-generated.