@@ -271,21 +271,6 @@ def cmd_wrapper(instance, cmdline):
271271 cmd_wrapper .__dict__ ['has_parser' ] = True
272272 setattr (cmd_wrapper , 'argparser' , argparser )
273273
274- # If there are subcommands, store their names in a list to support tab-completion of subcommand names
275- if argparser ._subparsers is not None :
276- # Key is subcommand name and value is completer function
277- subcommands = collections .OrderedDict ()
278-
279- # Get all subcommands and check if they have completer functions
280- for name , parser in argparser ._subparsers ._group_actions [0 ]._name_parser_map .items ():
281- if 'completer' in parser ._defaults :
282- completer = parser ._defaults ['completer' ]
283- else :
284- completer = None
285- subcommands [name ] = completer
286-
287- cmd_wrapper .__dict__ ['subcommands' ] = subcommands
288-
289274 return cmd_wrapper
290275
291276 return arg_decorator
@@ -324,22 +309,6 @@ def cmd_wrapper(instance, cmdline):
324309 cmd_wrapper .__dict__ ['has_parser' ] = True
325310 setattr (cmd_wrapper , 'argparser' , argparser )
326311
327- # If there are subcommands, store their names in a list to support tab-completion of subcommand names
328- if argparser ._subparsers is not None :
329-
330- # Key is subcommand name and value is completer function
331- subcommands = collections .OrderedDict ()
332-
333- # Get all subcommands and check if they have completer functions
334- for name , parser in argparser ._subparsers ._group_actions [0 ]._name_parser_map .items ():
335- if 'completer' in parser ._defaults :
336- completer = parser ._defaults ['completer' ]
337- else :
338- completer = None
339- subcommands [name ] = completer
340-
341- cmd_wrapper .__dict__ ['subcommands' ] = subcommands
342-
343312 return cmd_wrapper
344313
345314 return arg_decorator
@@ -1023,49 +992,6 @@ def colorize(self, val, color):
1023992 return self ._colorcodes [color ][True ] + val + self ._colorcodes [color ][False ]
1024993 return val
1025994
1026- def get_subcommands (self , command ):
1027- """
1028- Returns a list of a command's subcommand names if they exist
1029- :param command: the command we are querying
1030- :return: A subcommand list or None
1031- """
1032-
1033- subcommand_names = None
1034-
1035- # Check if is a valid command
1036- funcname = self ._func_named (command )
1037-
1038- if funcname :
1039- # Check to see if this function was decorated with an argparse ArgumentParser
1040- func = getattr (self , funcname )
1041- subcommands = func .__dict__ .get ('subcommands' , None )
1042- if subcommands is not None :
1043- subcommand_names = subcommands .keys ()
1044-
1045- return subcommand_names
1046-
1047- def get_subcommand_completer (self , command , subcommand ):
1048- """
1049- Returns a subcommand's tab completion function if one exists
1050- :param command: command which owns the subcommand
1051- :param subcommand: the subcommand we are querying
1052- :return: A completer or None
1053- """
1054-
1055- completer = None
1056-
1057- # Check if is a valid command
1058- funcname = self ._func_named (command )
1059-
1060- if funcname :
1061- # Check to see if this function was decorated with an argparse ArgumentParser
1062- func = getattr (self , funcname )
1063- subcommands = func .__dict__ .get ('subcommands' , None )
1064- if subcommands is not None :
1065- completer = subcommands [subcommand ]
1066-
1067- return completer
1068-
1069995 # ----- Methods related to tab completion -----
1070996
1071997 def set_completion_defaults (self ):
@@ -1797,10 +1723,11 @@ def complete(self, text, state):
17971723 try :
17981724 compfunc = getattr (self , 'complete_' + command )
17991725 except AttributeError :
1800-
1726+ # There's no completer function, next see if the command uses argparser
18011727 cmd_func = getattr (self , 'do_' + command )
18021728 if hasattr (cmd_func , 'has_parser' ) and hasattr (cmd_func , 'argparser' ) and \
18031729 getattr (cmd_func , 'has_parser' ):
1730+ # Command uses argparser, switch to the default argparse completer
18041731 argparser = getattr (cmd_func , 'argparser' )
18051732 compfunc = functools .partial (self ._autocomplete_default ,
18061733 argparser = argparser )
@@ -1975,6 +1902,7 @@ def complete_help(self, text, line, begidx, endidx):
19751902 strs_to_match = list (topics | visible_commands )
19761903 matches = self .basic_complete (text , line , begidx , endidx , strs_to_match )
19771904
1905+ # check if the command uses argparser
19781906 elif index >= subcmd_index and hasattr (self , 'do_' + tokens [cmd_index ]) and \
19791907 hasattr (getattr (self , 'do_' + tokens [cmd_index ]), 'has_parser' ):
19801908 command = tokens [cmd_index ]
@@ -1983,14 +1911,6 @@ def complete_help(self, text, line, begidx, endidx):
19831911 completer = AutoCompleter (parser )
19841912 matches = completer .complete_command_help (tokens [1 :], text , line , begidx , endidx )
19851913
1986-
1987- # Check if we are completing a subcommand
1988- elif index == subcmd_index :
1989-
1990- # Match subcommands if any exist
1991- command = tokens [cmd_index ]
1992- matches = self .basic_complete (text , line , begidx , endidx , self .get_subcommands (command ))
1993-
19941914 return matches
19951915
19961916 # noinspection PyUnusedLocal
@@ -2947,87 +2867,6 @@ def complete_shell(self, text, line, begidx, endidx):
29472867 index_dict = {1 : self .shell_cmd_complete }
29482868 return self .index_based_complete (text , line , begidx , endidx , index_dict , self .path_complete )
29492869
2950- def cmd_with_subs_completer (self , text , line , begidx , endidx ):
2951- """
2952- This is a function provided for convenience to those who want an easy way to add
2953- tab completion to functions that implement subcommands. By setting this as the
2954- completer of the base command function, the correct completer for the chosen subcommand
2955- will be called.
2956-
2957- The use of this function requires assigning a completer function to the subcommand's parser
2958- Example:
2959- A command called print has a subcommands called 'names' that needs a tab completer
2960- When you create the parser for names, include the completer function in the parser's defaults.
2961-
2962- names_parser.set_defaults(func=print_names, completer=complete_print_names)
2963-
2964- To make sure the names completer gets called, set the completer for the print function
2965- in a similar fashion to what follows.
2966-
2967- complete_print = cmd2.Cmd.cmd_with_subs_completer
2968-
2969- When the subcommand's completer is called, this function will have stripped off all content from the
2970- beginning of the command line before the subcommand, meaning the line parameter always starts with the
2971- subcommand name and the index parameters reflect this change.
2972-
2973- For instance, the command "print names -d 2" becomes "names -d 2"
2974- begidx and endidx are incremented accordingly
2975-
2976- :param text: str - the string prefix we are attempting to match (all returned matches must begin with it)
2977- :param line: str - the current input line with leading whitespace removed
2978- :param begidx: int - the beginning index of the prefix text
2979- :param endidx: int - the ending index of the prefix text
2980- :return: List[str] - a list of possible tab completions
2981- """
2982- # The command is the token at index 0 in the command line
2983- cmd_index = 0
2984-
2985- # The subcommand is the token at index 1 in the command line
2986- subcmd_index = 1
2987-
2988- # Get all tokens through the one being completed
2989- tokens , _ = self .tokens_for_completion (line , begidx , endidx )
2990- if tokens is None :
2991- return []
2992-
2993- matches = []
2994-
2995- # Get the index of the token being completed
2996- index = len (tokens ) - 1
2997-
2998- # If the token being completed is past the subcommand name, then do subcommand specific tab-completion
2999- if index > subcmd_index :
3000-
3001- # Get the command name
3002- command = tokens [cmd_index ]
3003-
3004- # Get the subcommand name
3005- subcommand = tokens [subcmd_index ]
3006-
3007- # Find the offset into line where the subcommand name begins
3008- subcmd_start = 0
3009- for cur_index in range (0 , subcmd_index + 1 ):
3010- cur_token = tokens [cur_index ]
3011- subcmd_start = line .find (cur_token , subcmd_start )
3012-
3013- if cur_index != subcmd_index :
3014- subcmd_start += len (cur_token )
3015-
3016- # Strip off everything before subcommand name
3017- orig_line = line
3018- line = line [subcmd_start :]
3019-
3020- # Update the indexes
3021- diff = len (orig_line ) - len (line )
3022- begidx -= diff
3023- endidx -= diff
3024-
3025- # Call the subcommand specific completer if it exists
3026- compfunc = self .get_subcommand_completer (command , subcommand )
3027- if compfunc is not None :
3028- matches = compfunc (self , text , line , begidx , endidx )
3029-
3030- return matches
30312870
30322871 # noinspection PyBroadException
30332872 def do_py (self , arg ):
0 commit comments