25
25
)
26
26
from .command_definition import CommandSet
27
27
from .table_creator import Column , SimpleTable
28
- from .utils import CompletionError , basic_complete , get_defining_class
28
+ from .utils import CompletionError , basic_complete
29
29
30
30
# If no descriptive header is supplied, then this will be used instead
31
31
DEFAULT_DESCRIPTIVE_HEADER = 'Description'
@@ -405,7 +405,7 @@ def update_mutex_groups(arg_action: argparse.Action) -> None:
405
405
406
406
# Check if we are completing a flag's argument
407
407
if flag_arg_state is not None :
408
- completion_results = self ._complete_for_arg (flag_arg_state . action , text , line ,
408
+ completion_results = self ._complete_for_arg (flag_arg_state , text , line ,
409
409
begidx , endidx , consumed_arg_values ,
410
410
cmd_set = cmd_set )
411
411
@@ -426,7 +426,7 @@ def update_mutex_groups(arg_action: argparse.Action) -> None:
426
426
action = remaining_positionals .popleft ()
427
427
pos_arg_state = _ArgumentState (action )
428
428
429
- completion_results = self ._complete_for_arg (pos_arg_state . action , text , line ,
429
+ completion_results = self ._complete_for_arg (pos_arg_state , text , line ,
430
430
begidx , endidx , consumed_arg_values ,
431
431
cmd_set = cmd_set )
432
432
@@ -461,7 +461,7 @@ def _complete_flags(self, text: str, line: str, begidx: int, endidx: int, matche
461
461
462
462
return basic_complete (text , line , begidx , endidx , match_against )
463
463
464
- def _format_completions (self , action , completions : List [Union [str , CompletionItem ]]) -> List [str ]:
464
+ def _format_completions (self , arg_state : _ArgumentState , completions : List [Union [str , CompletionItem ]]) -> List [str ]:
465
465
# Check if the results are CompletionItems and that there aren't too many to display
466
466
if 1 < len (completions ) <= self ._cmd2_app .max_completion_items and \
467
467
isinstance (completions [0 ], CompletionItem ):
@@ -472,9 +472,18 @@ def _format_completions(self, action, completions: List[Union[str, CompletionIte
472
472
self ._cmd2_app .matches_sorted = True
473
473
474
474
# If a metavar was defined, use that instead of the dest field
475
- destination = action .metavar if action .metavar else action .dest
476
-
477
- desc_header = getattr (action , ATTR_DESCRIPTIVE_COMPLETION_HEADER , None )
475
+ destination = arg_state .action .metavar if arg_state .action .metavar else arg_state .action .dest
476
+
477
+ # Handle case where metavar was a tuple
478
+ if isinstance (destination , tuple ):
479
+ # Figure out what string in the tuple to use based on how many of the arguments have been completed.
480
+ # Use min() to avoid going passed the end of the tuple to support nargs being ZERO_OR_MORE and
481
+ # ONE_OR_MORE. In those cases, argparse limits metavar tuple to 2 elements but we may be completing
482
+ # the 3rd or more argument here.
483
+ tuple_index = min (len (destination ) - 1 , arg_state .count )
484
+ destination = destination [tuple_index ]
485
+
486
+ desc_header = getattr (arg_state .action , ATTR_DESCRIPTIVE_COMPLETION_HEADER , None )
478
487
if desc_header is None :
479
488
desc_header = DEFAULT_DESCRIPTIVE_HEADER
480
489
@@ -546,7 +555,7 @@ def format_help(self, tokens: List[str]) -> str:
546
555
break
547
556
return self ._parser .format_help ()
548
557
549
- def _complete_for_arg (self , arg_action : argparse . Action ,
558
+ def _complete_for_arg (self , arg_state : _ArgumentState ,
550
559
text : str , line : str , begidx : int , endidx : int ,
551
560
consumed_arg_values : Dict [str , List [str ]], * ,
552
561
cmd_set : Optional [CommandSet ] = None ) -> List [str ]:
@@ -556,10 +565,10 @@ def _complete_for_arg(self, arg_action: argparse.Action,
556
565
:raises: CompletionError if the completer or choices function this calls raises one
557
566
"""
558
567
# Check if the arg provides choices to the user
559
- if arg_action .choices is not None :
560
- arg_choices = arg_action .choices
568
+ if arg_state . action .choices is not None :
569
+ arg_choices = arg_state . action .choices
561
570
else :
562
- arg_choices = getattr (arg_action , ATTR_CHOICES_CALLABLE , None )
571
+ arg_choices = getattr (arg_state . action , ATTR_CHOICES_CALLABLE , None )
563
572
564
573
if arg_choices is None :
565
574
return []
@@ -586,8 +595,8 @@ def _complete_for_arg(self, arg_action: argparse.Action,
586
595
arg_tokens = {** self ._parent_tokens , ** consumed_arg_values }
587
596
588
597
# Include the token being completed
589
- arg_tokens .setdefault (arg_action .dest , [])
590
- arg_tokens [arg_action .dest ].append (text )
598
+ arg_tokens .setdefault (arg_state . action .dest , [])
599
+ arg_tokens [arg_state . action .dest ].append (text )
591
600
592
601
# Add the namespace to the keyword arguments for the function we are calling
593
602
kwargs [ARG_TOKENS ] = arg_tokens
@@ -617,10 +626,10 @@ def _complete_for_arg(self, arg_action: argparse.Action,
617
626
arg_choices [index ] = str (choice )
618
627
619
628
# Filter out arguments we already used
620
- used_values = consumed_arg_values .get (arg_action .dest , [])
629
+ used_values = consumed_arg_values .get (arg_state . action .dest , [])
621
630
arg_choices = [choice for choice in arg_choices if choice not in used_values ]
622
631
623
632
# Do tab completion on the choices
624
633
results = basic_complete (text , line , begidx , endidx , arg_choices )
625
634
626
- return self ._format_completions (arg_action , results )
635
+ return self ._format_completions (arg_state , results )
0 commit comments