@@ -36,8 +36,8 @@ def cmd2_app():
3636
3737
3838# List of strings used with completion functions
39- food_item_strs = ['Pizza' , 'Hamburger' , 'Ham' , 'Potato' , 'Space Food' ]
40- sport_item_strs = ['Bat' , 'Basket' , 'Basketball' , 'Football' ]
39+ food_item_strs = ['Pizza' , 'Hamburger' , 'Ham' , 'Potato' ]
40+ sport_item_strs = ['Bat' , 'Basket' , 'Basketball' , 'Football' , 'Space Ball' ]
4141delimited_strs = ['/home/user/file.txt' , '/home/user/prog.c' , '/home/otheruser/maps' ]
4242
4343# Dictionary used with flag based completion functions
@@ -636,6 +636,15 @@ def base_bar(self, args):
636636 """bar subcommand of base command"""
637637 self .poutput ('((%s))' % args .z )
638638
639+ def base_sport (self , args ):
640+ """sport subcommand of base command"""
641+ self .poutput ('Sport is {}' .format (args .sport ))
642+
643+ def complete_base_sport (self , text , line , begidx , endidx ):
644+ """ Adds tab completion to base sport subcommand """
645+ index_dict = {1 : sport_item_strs }
646+ return self .index_based_complete (text , line , begidx , endidx , index_dict )
647+
639648 # create the top-level parser for the base command
640649 base_parser = argparse .ArgumentParser (prog = 'base' )
641650 base_subparsers = base_parser .add_subparsers (title = 'subcommands' , help = 'subcommand help' )
@@ -651,6 +660,11 @@ def base_bar(self, args):
651660 parser_bar .add_argument ('z' , help = 'string' )
652661 parser_bar .set_defaults (func = base_bar )
653662
663+ # create the parser for the "sport" subcommand
664+ parser_sport = base_subparsers .add_parser ('sport' , help = 'sport help' )
665+ parser_sport .add_argument ('sport' , help = 'Enter name of a sport' )
666+ parser_sport .set_defaults (func = base_sport )
667+
654668 @cmd2 .with_argparser (base_parser )
655669 def do_base (self , args ):
656670 """Base command help"""
@@ -662,6 +676,9 @@ def do_base(self, args):
662676 # No sub-command was provided, so as called
663677 self .do_help ('base' )
664678
679+ def complete_base (self , text , line , begidx , endidx ):
680+ return self .cmd_with_subs_completer (text , line , begidx , endidx , base = 'base' )
681+
665682
666683@pytest .fixture
667684def sc_app ():
@@ -687,7 +704,7 @@ def test_cmd2_subcommand_completion_multiple(sc_app):
687704 begidx = endidx - len (text )
688705
689706 first_match = complete_tester (text , line , begidx , endidx , sc_app )
690- assert first_match is not None and sc_app .completion_matches == ['bar' , 'foo' ]
707+ assert first_match is not None and sc_app .completion_matches == ['bar' , 'foo' , 'sport' ]
691708
692709def test_cmd2_subcommand_completion_nomatch (sc_app ):
693710 text = 'z'
@@ -712,7 +729,7 @@ def test_cmd2_help_subcommand_completion_multiple(sc_app):
712729 endidx = len (line )
713730 begidx = endidx - len (text )
714731
715- assert sc_app .complete_help (text , line , begidx , endidx ) == ['bar' , 'foo' ]
732+ assert sc_app .complete_help (text , line , begidx , endidx ) == ['bar' , 'foo' , 'sport' ]
716733
717734
718735def test_cmd2_help_subcommand_completion_nomatch (sc_app ):
@@ -722,6 +739,28 @@ def test_cmd2_help_subcommand_completion_nomatch(sc_app):
722739 begidx = endidx - len (text )
723740 assert sc_app .complete_help (text , line , begidx , endidx ) == []
724741
742+ def test_subcommand_tab_completion (sc_app ):
743+ # This makes sure the correct completer for the sport subcommand is called
744+ text = 'Foot'
745+ line = 'base sport Foot'
746+ endidx = len (line )
747+ begidx = endidx - len (text )
748+
749+ first_match = complete_tester (text , line , begidx , endidx , sc_app )
750+
751+ # It is at end of line, so extra space is present
752+ assert first_match is not None and sc_app .completion_matches == ['Football ' ]
753+
754+ def test_subcommand_tab_completion_with_no_completer (sc_app ):
755+ # This tests what happens when a subcommand has no completer
756+ # In this case, the foo subcommand has no completer defined
757+ text = 'Foot'
758+ line = 'base foo Foot'
759+ endidx = len (line )
760+ begidx = endidx - len (text )
761+
762+ first_match = complete_tester (text , line , begidx , endidx , sc_app )
763+ assert first_match is None
725764
726765class SecondLevel (cmd2 .Cmd ):
727766 """To be used as a second level command class. """
0 commit comments