if [[ $COMP_CWORD -le $cmd_index ]]; then
        # The user has not specified a command yet
        local all_commands="$(tmux -q list-commands | cut -f 1 -d ' ')"
        COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${all_commands}" -- "${cur}") )

I am trying to understand above code snippet for tmux bash autocompletion

compgen's W argument takes a word-list. But why does it taken an extra option -- with the current word, ${cur} as argument?

What does :- inside flower brackets mean?${COMPREPLY[@]:-}

When i do, tmux<tab> the completion list displayed is same as $(tmux -q list-commands | cut -f 1 -d ' '). So, why do we need ${COMPREPLY[@]:-} in the array beginning?

  • ... because the :-} smiley looks awesome? Joke aside, the -- likely is there to make it known that the next argument is not an option! My guess would be that Bash uses getopt internally, so it relies on these conventions?! Jul 27, 2015 at 15:31
  • :- is meant to remove the empty strings from inside the array.... So, need to understand what does double hypen mean as an argument to compgen...
    – user93868
    Jul 27, 2015 at 17:21

2 Answers 2


compgen -W "${all_commands}" -- "${cur}" runs compgen, passing it:

  • the option -W with one argument, the value of the variable all_commands;
  • one non-option argument, the value of the variable cur.

The -- argument marks the end of options. Even if the value of cur begins with a dash, it won't be interpreted as an option. This is an extremely common convention for command line option parsing.

${COMPREPLY[@]:-} is a weird one. It uses the parameter expansion construct ${VARIABLE:-TEXT}, which expands to the value of VARIABLE if set and non-empty and to TEXT otherwise, in a mostly pointless way. It takes the elements of the array COMPREPLY, except that if the array is empty or undefined, it results in an empty string. Then the result is split into words and each word is interpreted as a glob pattern. This is exactly equivalent to ${COMPREPLY[@]} except when COMPREPLY is not defined and set -u is in effect: under set -u, ${COMPREPLY[@]} would trigger an error if COMPREPLY is not defined. Note in particular that this instruction does not append to the COMPREPLY array, it mangles it. To append to the array, the right code would be

COMPREPLY+=($(compgen -W "${all_commands}" -- "${cur}") )

assuming that the output of compgen contains a whitespace-delimited list of glob patterns.


Double hyphen means the end of optional parameters and whatever follows hyphens need to be treated as positional parameters... read more @ What does "--" (double-dash) mean? (also known as "bare double dash").

And :- is meant to remove the empty strings from inside the array...

all issues solved.. thanks...

  • 1
    No, :- does not remove the empty strings from the array. That's one of the consequences of using an unquoted variable expansion; ${COMPREPLY[@]} would do it as well. Jul 28, 2015 at 0:40

You must log in to answer this question.