@@ -368,7 +368,7 @@ def complete_bash(parser, root_prefix=None, preamble="", choice_functions=None):
368368 current_action_nargs=1
369369 fi
370370
371- current_action_args_start_index=$(( $word_index + 1 ))
371+ current_action_args_start_index=$(( $word_index + 1 - $pos_only ))
372372
373373 current_action_is_positional=$2
374374}
@@ -395,6 +395,7 @@ def complete_bash(parser, root_prefix=None, preamble="", choice_functions=None):
395395
396396 local prefix=${root_prefix}
397397 local word_index=0
398+ local pos_only=0 # "--" delimeter not encountered yet
398399 _set_parser_defaults
399400 word_index=1
400401
@@ -403,34 +404,38 @@ def complete_bash(parser, root_prefix=None, preamble="", choice_functions=None):
403404 while [ $word_index -ne $COMP_CWORD ]; do
404405 local this_word="${COMP_WORDS[$word_index]}"
405406
406- if [[ -n $sub_parsers && " ${sub_parsers[@]} " == *" ${this_word} "* ]]; then
407- # valid subcommand: add it to the prefix & reset the current action
408- prefix="${prefix}_$(_shtab_replace_nonword $this_word)"
409- _set_parser_defaults
410- fi
411-
412- if [[ " ${current_option_strings[@]} " == *" ${this_word} "* ]]; then
413- # a new action should be acquired (due to recognised option string or
414- # no more input expected from current action);
415- # the next positional action can fill in here
416- _set_new_action $this_word false
417- fi
418-
419- if [[ "$current_action_nargs" != "*" ]] && \\
420- [[ "$current_action_nargs" != "+" ]] && \\
421- [[ "$current_action_nargs" != *"..." ]] && \\
422- (( $word_index + 1 - $current_action_args_start_index >= \\
423- $current_action_nargs )); then
424- $current_action_is_positional && let "completed_positional_actions += 1"
425- _set_new_action "pos_${completed_positional_actions}" true
407+ if [[ $pos_only = 1 || " $this_word " != " -- " ]]; then
408+ if [[ -n $sub_parsers && " ${sub_parsers[@]} " == *" ${this_word} "* ]]; then
409+ # valid subcommand: add it to the prefix & reset the current action
410+ prefix="${prefix}_$(_shtab_replace_nonword $this_word)"
411+ _set_parser_defaults
412+ fi
413+
414+ if [[ " ${current_option_strings[@]} " == *" ${this_word} "* ]]; then
415+ # a new action should be acquired (due to recognised option string or
416+ # no more input expected from current action);
417+ # the next positional action can fill in here
418+ _set_new_action $this_word false
419+ fi
420+
421+ if [[ "$current_action_nargs" != "*" ]] && \\
422+ [[ "$current_action_nargs" != "+" ]] && \\
423+ [[ "$current_action_nargs" != *"..." ]] && \\
424+ (( $word_index + 1 - $current_action_args_start_index - $pos_only >= \\
425+ $current_action_nargs )); then
426+ $current_action_is_positional && let "completed_positional_actions += 1"
427+ _set_new_action "pos_${completed_positional_actions}" true
428+ fi
429+ else
430+ pos_only=1 # "--" delimeter encountered
426431 fi
427432
428433 let "word_index+=1"
429434 done
430435
431436 # Generate the completions
432437
433- if [[ "${completing_word}" == -* ]]; then
438+ if [[ $pos_only = 0 && "${completing_word}" == -* ]]; then
434439 # optional argument started: use option strings
435440 COMPREPLY=( $(compgen -W "${current_option_strings[*]}" -- "${completing_word}") )
436441 else
0 commit comments