@@ -209,6 +209,8 @@ class RlType(Enum):
209209# Used for tab completion and word breaks. Do not change.
210210QUOTES = ['"' , "'" ]
211211REDIRECTION_CHARS = ['|' , '<' , '>' ]
212+
213+ # optional attribute, when tagged on a function, allows cmd2 to categorize commands
212214HELP_CATEGORY = 'help_category'
213215
214216
@@ -2891,7 +2893,10 @@ def complete_unalias(self, text, line, begidx, endidx):
28912893 @with_argument_list
28922894 def do_help (self , arglist ):
28932895 """List available commands with "help" or detailed help with "help cmd"."""
2894- if arglist :
2896+ if not arglist or (len (arglist ) == 1 and arglist [0 ] in ('--verbose' , '-v' )):
2897+ verbose = len (arglist ) == 1 and arglist [0 ] in ('--verbose' , '-v' )
2898+ self ._help_menu (verbose )
2899+ else :
28952900 # Getting help for a specific command
28962901 funcname = self ._func_named (arglist [0 ])
28972902 if funcname :
@@ -2912,11 +2917,8 @@ def do_help(self, arglist):
29122917 else :
29132918 # This could be a help topic
29142919 cmd .Cmd .do_help (self , arglist [0 ])
2915- else :
2916- # Show a menu of what commands help can be gotten for
2917- self ._help_menu ()
29182920
2919- def _help_menu (self ):
2921+ def _help_menu (self , verbose = False ):
29202922 """Show a list of commands which help can be displayed for.
29212923 """
29222924 # Get a sorted list of help topics
@@ -2947,19 +2949,62 @@ def _help_menu(self):
29472949
29482950 if len (cmds_cats ) == 0 :
29492951 # No categories found, fall back to standard behavior
2950- self .poutput ("%s \n " % str (self .doc_leader ))
2951- self .print_topics (self .doc_header , cmds_doc , 15 , 80 )
2952+ self .poutput ("{} \n " . format ( str (self .doc_leader ) ))
2953+ self ._print_topics (self .doc_header , cmds_doc , verbose )
29522954 else :
29532955 # Categories found, Organize all commands by category
2954- self .poutput ("%s\n " % str (self .doc_leader ))
2955- self .poutput ("%s\n \n " % str (self .doc_header ))
2956- for category in cmds_cats :
2957- self .print_topics (category , cmds_cats [category ], 15 , 80 )
2958- self .print_topics ('Other' , cmds_doc , 15 , 80 )
2956+ self .poutput ('{}\n ' .format (str (self .doc_leader )))
2957+ self .poutput ('{}\n \n ' .format (str (self .doc_header )))
2958+ for category in sorted (cmds_cats .keys ()):
2959+ self ._print_topics (category , cmds_cats [category ], verbose )
2960+ self ._print_topics ('Other' , cmds_doc , verbose )
2961+
29592962
29602963 self .print_topics (self .misc_header , help_topics , 15 , 80 )
29612964 self .print_topics (self .undoc_header , cmds_undoc , 15 , 80 )
29622965
2966+ def _print_topics (self , header , cmds , verbose ):
2967+ """Customized version of print_topics that can switch between verbose or traditional output"""
2968+ if cmds :
2969+ if not verbose :
2970+ self .print_topics (header , cmds , 15 , 80 )
2971+ else :
2972+ self .stdout .write ('{}\n ' .format (str (header )))
2973+ widest = 0
2974+ # measure the commands
2975+ for command in cmds :
2976+ width = wcswidth (command )
2977+ if width > widest :
2978+ widest = width
2979+ # add a 4-space pad
2980+ widest += 4
2981+ if widest < 20 :
2982+ widest = 20
2983+
2984+ if self .ruler :
2985+ self .stdout .write ('{:{ruler}<{width}}\n ' .format ('' , ruler = self .ruler , width = 80 ))
2986+
2987+ for command in cmds :
2988+ # Attempt to locate the first documentation block
2989+ doc = getattr (self , self ._func_named (command )).__doc__
2990+ doc_block = []
2991+ found_first = False
2992+ for doc_line in doc .splitlines ():
2993+ str (doc_line ).strip ()
2994+ if len (doc_line .strip ()) > 0 :
2995+ doc_block .append (doc_line .strip ())
2996+ found_first = True
2997+ else :
2998+ if found_first :
2999+ break
3000+
3001+ for doc_line in doc_block :
3002+ self .stdout .write ('{: <{col_width}}{doc}\n ' .format (command ,
3003+ col_width = widest ,
3004+ doc = doc_line ))
3005+ command = ''
3006+ self .stdout .write ("\n " )
3007+
29633008 def do_shortcuts (self , _ ):
29643009 """Lists shortcuts (aliases) available."""
29653010 result = "\n " .join ('%s: %s' % (sc [0 ], sc [1 ]) for sc in sorted (self .shortcuts ))
@@ -3226,6 +3271,8 @@ def cmd_with_subs_completer(self, text, line, begidx, endidx):
32263271 # noinspection PyBroadException
32273272 def do_py (self , arg ):
32283273 """
3274+ Invoke python command, shell, or script
3275+
32293276 py <command>: Executes a Python command.
32303277 py: Enters interactive Python mode.
32313278 End with ``Ctrl-D`` (Unix) / ``Ctrl-Z`` (Windows), ``quit()``, '`exit()``.
0 commit comments