Added the ability to provide a completer for arguments to options
authorDmitriy Morozov <dmitriy@mrzv.org>
Sat, 29 May 2010 15:46:31 -0700
changeset 105 1ce5c137b3e5
parent 104 307ed799be32
child 106 139707873c14
child 116 48cda0ae3913
Added the ability to provide a completer for arguments to options
opster.py
--- a/opster.py	Thu Feb 25 10:13:55 2010 -0800
+++ b/opster.py	Sat May 29 15:46:31 2010 -0700
@@ -127,7 +127,7 @@
                               [('b', 'bash', False, 'Output bash competion'), 
                                ('z', 'zsh',  False, 'Output zsh completion')], 
                               '--bash OR --zsh')
-    autocomplete(cmdtable, args)
+    autocomplete(cmdtable, args, middleware)
 
     try:
         name, func, args, kwargs = catcher(
@@ -282,7 +282,8 @@
     argmap, defmap, state = {}, {}, {}
     shortlist, namelist, funlist = '', [], []
 
-    for short, name, default, comment in options:
+    for o in options:
+        short, name, default, comment = o[:4]       # might have the fifth completer element
         if short and len(short) != 1:
             raise FOError('Short option should be only a single'
                           ' character: %s' % short)
@@ -342,7 +343,7 @@
 # --------
 
 # Borrowed from PIP
-def autocomplete(cmdtable, args):
+def autocomplete(cmdtable, args, middleware):
     """Command and option completion.
 
     Enable by sourcing one of the completion shell scripts (bash or zsh).
@@ -369,14 +370,21 @@
     
     # command options
     elif cwords[0] in commands:
+        idx = -2 if current else -1
         options = []
         aliases, (cmd, opts, usage) = findcmd(cwords[0], cmdtable)
-        for (short, long, default, help) in opts:
-            options.append('-%s'  % short)
-            options.append('--%s' % long)
+
+        for o in opts:
+            short, long, default, help = o[:4]
+            completer = o[4] if len(o) > 4 else None
+            short, long = '-%s' % short, '--%s' % long
+            options += [short,long]
+
+            if (cwords[idx] in [short,long]) and completer:
+                args = middleware(completer)(current)
+                print ' '.join(args),
         
-        options = [o for o in options if o.startswith(current)]
-        print ' '.join(filter(lambda x: x.startswith(current), options))
+        print ' '.join((o for o in options if o.startswith(current)))
     
     sys.exit(1)
 
@@ -503,8 +511,9 @@
     args, varargs, varkw, defaults = inspect.getargspec(func)
     for name, option in zip(args[-len(defaults):], defaults):
         try:
-            sname, default, hlp = option
-            yield (sname, name.replace('_', '-'), default, hlp)
+            sname, default, hlp = option[:3]
+            completer = option[3] if len(option) > 3 else None
+            yield (sname, name.replace('_', '-'), default, hlp, completer)
         except TypeError:
             pass