Manu
Manu

Reputation: 364

Bash Autocompletion with multiple argument values per argument

I'm trying to implement tab completion for the first time - it has to work in GIT Bash and its for a python script that i wrote (done with argparser)

The script basically has two arguments --option_a and --option_b and they accept both single and multiple argument values, e.g. script --option_a steak or script --option_a steak burger pizza are both valid. There's still a set of choices to choose from though, so you cannot enter whatever you like.

I already got most of it done:

What's already done

OPTION_A_VALUES="bread pizza steak burger"
OPTION_B_VALUES="apple banana"

_autocomplete () {                
  COMPREPLY=()   
  local cur=${COMP_WORDS[COMP_CWORD]}
  local prev=${COMP_WORDS[COMP_CWORD-1]}

  case "$prev" in
   "--option_a")
       COMPREPLY=( $( compgen -W "$OPTION_A_VALUES" -- $cur ) )  
       return 0 
       ;;
  "--option_b")
        COMPREPLY=( $( compgen -W "$OPTION_B_VALUES" -- $cur ) )
        return 0 
       ;;
 esac

  if [[ ${cur} == -* ]]
    then
      COMPREPLY=($(compgen -W "--option_a --option_b" -- $cur ) )
    return 0
  fi
}

complete -o nospace -F _autocomplete script

script is the alias for the python script.

The problem

Basically what i still need to do is supporting autocompletion for all the possible argument values - currently it stops after completing one:

Of course, after completing to pizza and typing --<TAB><TAB> the script should again suggest --option_a --option_b

Any help on how to modify my autocomplete script to make this work would be greatly appreciated! Thanks in advance.

Upvotes: 4

Views: 1749

Answers (1)

nhatnq
nhatnq

Reputation: 1193

You can try this

_autocomplete () {
  COMPREPLY=()
  local cur=${COMP_WORDS[COMP_CWORD]}
  local prev=${COMP_WORDS[COMP_CWORD-1]}

  if [[ ${cur} == -* ]]
    then
      COMPREPLY=($(compgen -W "--option_a --option_b" -- $cur ) )
    return 0
  fi

  case "$prev" in
   --option_a|bread|pizza|steak|burger)
       COMPREPLY=( $( compgen -W "$OPTION_A_VALUES" -- $cur ) )
       return 0
       ;;
   --option_b|apple|banana)
       COMPREPLY=( $( compgen -W "$OPTION_B_VALUES" -- $cur ) )
       return 0
       ;;
 esac

}

The idea is

If the cur starts with -, the compgen gets option_a option_b immediately

If the prev is one of --option_a bread pizza steak burger, it gets the values again

Upvotes: 3

Related Questions