@@ -318,6 +318,7 @@ def complete_command(self, tokens: List[str], text: str, line: str, begidx: int,
318318 flag_arg = AutoCompleter ._ArgumentState ()
319319 flag_action = None
320320
321+ # dict is used because object wrapper is necessary to allow inner functions to modify outer variables
321322 remainder = {'arg' : None , 'action' : None }
322323
323324 matched_flags = []
@@ -334,7 +335,8 @@ def consume_flag_argument() -> None:
334335 """Consuming token as a flag argument"""
335336 # we're consuming flag arguments
336337 # if this is not empty and is not another potential flag, count towards flag arguments
337- if token and token [0 ] not in self ._parser .prefix_chars and flag_action is not None :
338+ # if the token is a single character length, it doesn't matter that it matches a flag prefix
339+ if token and (len (token ) == 1 or token [0 ] not in self ._parser .prefix_chars ) and flag_action is not None :
338340 flag_arg .count += 1
339341
340342 # does this complete a option item for the flag
@@ -377,7 +379,6 @@ def process_action_nargs(action: argparse.Action, arg_state: AutoCompleter._Argu
377379 arg_state .max = float ('inf' )
378380 arg_state .variable = True
379381 if action .nargs == argparse .REMAINDER :
380- print ("Setting remainder" )
381382 remainder ['action' ] = action
382383 remainder ['arg' ] = arg_state
383384 elif action .nargs == '?' :
@@ -407,25 +408,35 @@ def process_action_nargs(action: argparse.Action, arg_state: AutoCompleter._Argu
407408 is_last_token = idx >= len (tokens ) - 1
408409 # Only start at the start token index
409410 if idx >= self ._token_start_index :
411+ # If a remainder action is found, force all future tokens to go to that
410412 if remainder ['arg' ] is not None :
411- print ("In Remainder mode" )
412413 if remainder ['action' ] == pos_action :
413414 consume_positional_argument ()
414415 continue
415416 elif remainder ['action' ] == flag_action :
416417 consume_flag_argument ()
417418 continue
418- else :
419- print ("!!" )
420419 current_is_positional = False
421420 # Are we consuming flag arguments?
422421 if not flag_arg .needed :
422+ # Special case when each of the following is true:
423+ # - We're not in the middle of consuming flag arguments
424+ # - The current positional argument count has hit the max count
425+ # - The next positional argument is a REMAINDER argument
426+ # Argparse will now treat all future tokens as arguments to the positional including tokens that look like flags
427+ # so the completer should skip any flag related processing once this happens
428+ skip_flag = False
429+ if (pos_action is not None ) and pos_arg .count >= pos_arg .max and next_pos_arg_index < len (self ._positional_actions ) and \
430+ self ._positional_actions [next_pos_arg_index ].nargs == argparse .REMAINDER :
431+ skip_flag = True
432+
433+
423434 # At this point we're no longer consuming flag arguments. Is the current argument a potential flag?
424435 # If the argument is the start of a flag and this is the last token, we proceed forward to try
425436 # and match against our known flags.
426437 # If this argument is not the last token and the argument is exactly a flag prefix, then this
427438 # token should be consumed as an argument to a prior flag or positional argument.
428- if len (token ) > 0 and token [0 ] in self ._parser .prefix_chars and \
439+ if len (token ) > 0 and token [0 ] in self ._parser .prefix_chars and not skip_flag and \
429440 (is_last_token or (not is_last_token and token not in self ._parser .prefix_chars )):
430441 # reset some tracking values
431442 flag_arg .reset ()
0 commit comments