diff options
Diffstat (limited to 'libbe/cmdutil.py')
-rw-r--r-- | libbe/cmdutil.py | 84 |
1 files changed, 72 insertions, 12 deletions
diff --git a/libbe/cmdutil.py b/libbe/cmdutil.py index 6d7ab01..6be7540 100644 --- a/libbe/cmdutil.py +++ b/libbe/cmdutil.py @@ -16,14 +16,15 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import optparse import os -import locale from textwrap import TextWrapper from StringIO import StringIO +import sys import doctest import bugdir import plugin -import utility +import encoding + class UserError(Exception): def __init__(self, msg): @@ -34,6 +35,18 @@ class UserErrorWrap(UserError): UserError.__init__(self, str(exception)) self.exception = exception +class UsageError(Exception): + pass + +class GetHelp(Exception): + pass + +class GetCompletions(Exception): + def __init__(self, completions=[]): + msg = "Get allowed completions" + Exception.__init__(self, msg) + self.completions = completions + def iter_commands(): for name, module in plugin.iter_plugins("becommands"): yield name.replace("_", "-"), module @@ -52,9 +65,11 @@ def get_command(command_name): raise UserError("Unknown command %s" % command_name) return cmd + def execute(cmd, args): - encoding = locale.getpreferredencoding() or 'ascii' - return get_command(cmd).execute([a.decode(encoding) for a in args]) + enc = encoding.get_encoding() + get_command(cmd).execute([a.decode(enc) for a in args]) + return 0 def help(cmd=None): if cmd != None: @@ -71,24 +86,30 @@ def help(cmd=None): ret.append("be %s%*s %s" % (name, numExtraSpaces, "", desc)) return "\n".join(ret) -class GetHelp(Exception): - pass - - -class UsageError(Exception): - pass - +def completions(cmd): + parser = get_command(cmd).get_parser() + longopts = [] + for opt in parser.option_list: + longopts.append(opt.get_opt_string()) + return longopts def raise_get_help(option, opt, value, parser): raise GetHelp - +def raise_get_completions(option, opt, value, parser): + print "got completion arg" + raise GetCompletions(completions(sys.argv[1])) + class CmdOptionParser(optparse.OptionParser): def __init__(self, usage): optparse.OptionParser.__init__(self, usage) + self.disable_interspersed_args() self.remove_option("-h") self.add_option("-h", "--help", action="callback", callback=raise_get_help, help="Print a help message") + self.add_option("--complete", action="callback", + callback=raise_get_completions, + help="Print a list of available completions") def error(self, message): raise UsageError(message) @@ -102,6 +123,45 @@ class CmdOptionParser(optparse.OptionParser): self.print_help(f) return f.getvalue() +def option_value_pairs(options, parser): + """ + Iterate through OptionParser (option, value) pairs. + """ + for option in [o.dest for o in parser.option_list if o.dest != None]: + value = getattr(options, option) + yield (option, value) + +def default_complete(options, args, parser, bugid_args={}): + """ + A dud complete implementation for becommands to that the + --complete argument doesn't cause any problems. Use this + until you've set up a command-specific complete function. + + bugid_args is an optional dict where the keys are positional + arguments taking bug shortnames and the values are functions for + filtering, since that's a common enough operation. + e.g. for "be open [options] BUGID" + bugid_args = {0: lambda bug : bug.active == False} + """ + for option,value in option_value_pairs(options, parser): + if value == "--complete": + raise cmdutil.GetCompletions() + for pos,value in enumerate(args): + if value == "--complete": + if pos in bugid_args: + filter = bugid_args[pos] + bugshortnames = [] + try: + bd = bugdir.BugDir(from_disk=True, + manipulate_encodings=False) + bd.load_all_bugs() + bugs = [bug for bug in bd if filter(bug) == True] + bugshortnames = [bd.bug_shortname(bug) for bug in bugs] + except bugdir.NoBugDir: + pass + raise GetCompletions(bugshortnames) + raise GetCompletions() + def underlined(instring): """Produces a version of a string that is underlined with '=' |