merge completer improvements
authorAlexander Solovyov <piranha@piranha.org.ua>
Sat, 11 Sep 2010 10:39:15 +0300
changeset 116 48cda0ae3913
parent 115 b0d1129c76bc (current diff)
parent 105 1ce5c137b3e5 (diff)
child 117 e17bf1d5c289
child 118 51f4b89d6c8d
merge completer improvements
opster.py
--- a/opster.py	Sat Apr 10 12:15:59 2010 +0300
+++ b/opster.py	Sat Sep 11 10:39:15 2010 +0300
@@ -123,15 +123,20 @@
     cmdtable['help'] = (help_(cmdtable, globaloptions), [], '[TOPIC]')
     help_func = cmdtable['help'][0]
 
-    autocomplete(cmdtable, args)
+    autocomplete(cmdtable, args, middleware)
 
     try:
         name, func, args, kwargs = catcher(
             lambda: _dispatch(args, cmdtable, globaloptions),
             help_func)
-        return catcher(
-            lambda: call_cmd(name, middleware(func))(*args, **kwargs),
-            help_func)
+        if name == '_completion':       # skip middleware
+            return catcher(
+                lambda: call_cmd(name, func)(*args, **kwargs),
+                help_func)
+        else:
+            return catcher(
+                lambda: call_cmd(name, middleware(func))(*args, **kwargs),
+                help_func)
     except Abort:
         return -1
 
@@ -233,7 +238,8 @@
 def help_options(options):
     yield 'options:\n\n'
     output = []
-    for short, name, default, desc in options:
+    for o in options:
+        short, name, default, desc = o[:4]
         if hasattr(default, '__call__'):
             default = default(None)
         default = default and ' (default: %s)' % default or ''
@@ -273,7 +279,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)
@@ -323,6 +330,9 @@
         state[name] = defmap[name](None)
 
     return state, args
+
+
+
 # --------
 # Subcommand system
 # --------
@@ -412,8 +422,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
 
@@ -513,7 +524,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).
@@ -540,18 +551,24 @@
 
     # 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)
 
-        options = [o for o in options if o.startswith(current)]
-        print ' '.join(filter(lambda x: x.startswith(current), options))
+        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),
+
+        print ' '.join((o for o in options if o.startswith(current)))
 
     sys.exit(1)
 
-
 COMPLETIONS = {
     'bash':
         """