--- 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':
"""