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") ) }
source share