Full equal command options

I am trying to write a Bash completion script for commands that can take long parameters in the form of --option or --param=value . If the user has already entered an option on the command line, this parameter should be excluded from the completion list (provided that it makes sense to specify only one parameter on the command line).

Here is the first attempt:

 _myprog() { local cur="${COMP_WORDS[$COMP_CWORD]}" local words=(--help --param1= --param-state --param2=) _exclude_cmd_line_opts COMPREPLY=( $(compgen -W "${words[*]}" -- "$cur") ) } complete -F _myprog myprog _exclude_cmd_line_opts() { local len=$(($COMP_CWORD - 1)) local i for i in "${COMP_WORDS[@]:1:$len}" ; do [[ $i == --* ]] && words=( "${words[@]/$i}" ) done } 

If the source is this script source script.sh , then write:

 $ myprog --param1= <tab><tab> 

I get the following list of completions:

 = --help --param2= --param-state 

so it works almost except that I get a false '=' in the completion list. Any suggestions?

+5
source share
1 answer

Entering an equal sign on the command line terminates the word due to the default contents of COMP_WORDBREAKS . Apparently, the effect is that the equal sign is included as a separate word in COMP_WORDS . This is used in the following modification of _exclude_cmd_line_opts :

 _exclude_cmd_line_opts() { local len=$(($COMP_CWORD - 1)) local i for ((i=1 ; i<=len; i++)) ; do local j="${COMP_WORDS[$i]}" if [[ $j == --* ]] ; then (( i<len )) && [[ ${COMP_WORDS[$(( i + 1))]} == '=' ]] && j="$j=" words=( "${words[@]/$j}" ) fi done } 

The problem with the original version of _exclude_cmd_line_opts was that ${words[@]/$j} returned false = when, for example, words=(param1=) and j="param1" (note the missing equal sign in $j that was called by COMP_WORDBREAKS ) ..

Refresh

I discovered another feature. In the above cases, it worked fine, because I never had to enter <tab> immediately after the = sign. However, if, for example, words=(--param= --param-info) and I enter --par<tab> , there are still two candidates, and the current words are only partially completed to become --param . With this, I would like to select the first of the two candidates, and I type the explicit = sign on the command line, and then type <tab> , what happens now when Bash thinks you have typed a space (with COMP_WORDBREAKS contains = ), and the current word completion varies from --param= to = . This will again make the Bash readline omit insert regular space, so the user is forced to enter a space to continue with the next option.

In this case, you can avoid entering a space by returning an COMPREPLY array with an empty string.

 _myprog() { local cur="${COMP_WORDS[$COMP_CWORD]}" local prev="" (( COMP_CWORD > 0 )) && prev="${COMP_WORDS[$(( COMP_CWORD - 1))]}" [[ $cur == '=' && $prev == --* ]] && { COMPREPLY=( "" ); return; } local words=(--param= --param-info) _exclude_cmd_line_opts COMPREPLY=( $(compgen -W "${words[*]}" -- "$cur") ) } 
+2
source

All Articles