changeset 290:cd12e4e0fa17

show -l working
author catherine@bothari
date Fri, 06 Nov 2009 21:41:55 -0500
parents 327ace491fa9
children dfdbd93a2fae
files cmd2.py example/example.py
diffstat 2 files changed, 69 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/cmd2.py	Thu Oct 29 16:17:58 2009 -0400
+++ b/cmd2.py	Fri Nov 06 21:41:55 2009 -0500
@@ -297,6 +297,15 @@
             if softspace(sys.stdout, 0):
                 print
 
+def ljust(x, width, fillchar=' '):
+    'analogous to str.ljust, but works for lists'
+    if hasattr(x, 'ljust'):
+        return x.ljust(width, fillchar)
+    else:
+        if len(x) < width:
+            x = (x + [fillchar] * width)[:width]
+        return x
+    
 class Cmd(cmd.Cmd):
     echo = False
     case_insensitive = True     # Commands recognized regardless of case
@@ -315,10 +324,19 @@
     feedback_to_output = False          # Do include nonessentials in >, | output
     quiet = False                       # Do not suppress nonessential output
     debug = False
-    settable = ['prompt', 'continuation_prompt', 'debug', 'default_file_name', 'editor',
-                'case_insensitive', 'feedback_to_output', 'quiet', 'echo', 'timing', 
-                'abbrev']   
-    settable.sort()
+    settable = '''
+        prompt
+        continuation_prompt
+        debug
+        default_file_name     for `save`, `load`, etc.
+        editor
+        case_insensitive      upper- and lower-case both OK
+        feedback_to_output    include nonessentials in `|`, `>` results 
+        quiet                 
+        echo                  Echo command issued into output
+        timing                Report execution times
+        abbrev                Accept abbreviated commands
+        '''.splitlines()
     
     def poutput(self, msg):
         if msg:
@@ -378,7 +396,10 @@
         self.pystate = {}
         self.shortcuts = sorted(self.shortcuts.items(), reverse=True)
         self.keywords = self.reserved_words + [fname[3:] for fname in dir(self) 
-                                               if fname.startswith('do_')]        
+                                               if fname.startswith('do_')] 
+        self.settable = (l.strip() for l in self.settable if l.strip())
+        self.settable = dict(ljust(l.split(None,1), 2, '') for l in self.settable)
+            
     def do_shortcuts(self, args):
         """Lists single-key shortcuts available."""
         result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in sorted(self.shortcuts))
@@ -801,54 +822,59 @@
     def do_EOF(self, arg):
         return True
     do_eof = do_EOF
-               
-    def show_param(self, param):
-        any_shown = False
-        param = param.strip().lower()
-        for p in self.settable:
-            if p.startswith(param):
-                self.stdout.write('%s: %s\n' % (p, str(getattr(self, p))))
-                any_shown = True
-        if not any_shown:
-            self.perror("Parameter '%s' not supported (type 'show' for list of parameters)." % param)
-                
+                           
     def do_quit(self, arg):
         return self._STOP_AND_EXIT
     do_exit = do_quit
     do_q = do_quit
     
-    def do_show(self, arg):
+    @options([make_option('-l', '--long', action="store_true",
+                 help="describe function of parameter")])    
+    def do_show(self, arg, opts):
         '''Shows value of a parameter.'''
-        if arg.strip():
-            self.show_param(arg)
+        param = arg.strip().lower()
+        result = {}
+        maxlen = 0
+        for p in self.settable:
+            if (not param) or p.startswith(param):
+                result[p] = '%s: %s' % (p, str(getattr(self, p)))
+                maxlen = max(maxlen, len(result[p]))
+        if result:
+            for p in sorted(result):
+                if opts.long:
+                    self.poutput('%s # %s' % (result[p].ljust(maxlen), self.settable[p]))
+                else:
+                    self.poutput(result[p])
         else:
-            for param in self.settable:
-                self.show_param(param)
+            self.perror("Parameter '%s' not supported (type 'show' for list of parameters)." % param)
     
     def do_set(self, arg):
-        '''Sets a cmd2 parameter.  Accepts abbreviated parameter names so long as there is no ambiguity.
-           Call without arguments for a list of settable parameters with their values.'''
+        '''
+        Sets a cmd2 parameter.  Accepts abbreviated parameter names so long
+        as there is no ambiguity.  Call without arguments for a list of 
+        settable parameters with their values.'''
         try:
             paramName, val = arg.split(None, 1)
             paramName = paramName.strip().lower()
-            hits = [paramName in p for p in self.settable]
-            if hits.count(True) == 1:
-                paramName = self.settable[hits.index(True)]
-                currentVal = getattr(self, paramName)
-                if (val[0] == val[-1]) and val[0] in ("'", '"'):
-                    val = val[1:-1]
-                else:                
-                    val = cast(currentVal, val)
-                setattr(self, paramName, val)
-                self.stdout.write('%s - was: %s\nnow: %s\n' % (paramName, currentVal, val))
-                if currentVal != val:
-                    try:
-                        onchange_hook = getattr(self, '_onchange_%s' % paramName)
-                        onchange_hook(old=currentVal, new=val)
-                    except AttributeError:
-                        pass
-            else:
-                self.do_show(paramName)
+            if paramName not in self.settable:
+                hits = [p for p in self.settable if p.startswith(p)]
+                if len(hits) == 1:
+                    paramName = hits[0]
+                else:
+                    return self.do_show(paramName)
+            currentVal = getattr(self, paramName)
+            if (val[0] == val[-1]) and val[0] in ("'", '"'):
+                val = val[1:-1]
+            else:                
+                val = cast(currentVal, val)
+            setattr(self, paramName, val)
+            self.stdout.write('%s - was: %s\nnow: %s\n' % (paramName, currentVal, val))
+            if currentVal != val:
+                try:
+                    onchange_hook = getattr(self, '_onchange_%s' % paramName)
+                    onchange_hook(old=currentVal, new=val)
+                except AttributeError:
+                    pass
         except (ValueError, AttributeError, NotSettableError), e:
             self.do_show(arg)
                 
@@ -1244,7 +1270,6 @@
         
 if __name__ == '__main__':
     doctest.testmod(optionflags = doctest.NORMALIZE_WHITESPACE)
-
     
 '''
 To make your application transcript-testable, add text like this to your .py file
--- a/example/example.py	Thu Oct 29 16:17:58 2009 -0400
+++ b/example/example.py	Fri Nov 06 21:41:55 2009 -0500
@@ -7,7 +7,7 @@
     multilineCommands = ['orate']
     Cmd.shortcuts.update({'&': 'speak'})
     maxrepeats = 3
-    Cmd.settable.append('maxrepeats')
+    Cmd.settable.append('maxrepeats   Max number of `--repeat` allowed')
 
     @options([make_option('-p', '--piglatin', action="store_true", help="atinLay"),
               make_option('-s', '--shout', action="store_true", help="N00B EMULATION MODE"),
@@ -43,6 +43,5 @@
     sys.argv = [sys.argv[0]] # the --test argument upsets unittest.main()
     unittest.main()
 else:
-    pass
-    #CmdLineApp().cmdloop()
+    CmdLineApp().cmdloop()