I'm still working on a clean implementation though...
--- /dev/null
+A rough implemention is now sketched out in becommands/list.py
--- /dev/null
+
+
+
+Content-type=text/plain
+
+
+
+
+
+
+Date=Thu, 27 Nov 2008 14:26:18 +0000
+
+
+
+
+
+
+From=W. Trevor King <wking@drexel.edu>
+
+
+
--- /dev/null
+For example:
+ $ be list --status --options
+ File "/home/wking/bin/be", line 35, in <module>
+ sys.exit(cmdutil.execute(sys.argv[1], sys.argv[2:]))
+ File "/home/wking/lib/python2.5/site-packages/libbe/cmdutil.py", line 67, in execute
+ get_command(cmd).execute([a.decode(enc) for a in args])
+ File "/home/wking/lib/python2.5/site-packages/becommands/list.py", line 36, in execute
+ raise Exception, "parsed options"
+ Exception: parsed options
+
+The reason for this is that --status takes an argument, so 'be list'
+thinks it should list all the bugs with status == "--options".
+Ideally what should happen is that an argument-taking option would
+check for argument --options, and if so, would raise an exception
+returning a list of appropriate completions *for that argument*.
--- /dev/null
+
+
+
+Content-type=text/plain
+
+
+
+
+
+
+Date=Thu, 27 Nov 2008 13:43:47 +0000
+
+
+
+
+
+
+From=W. Trevor King <wking@drexel.edu>
+
+
+
--- /dev/null
+
+
+
+creator=W. Trevor King <wking@drexel.edu>
+
+
+
+
+
+
+severity=serious
+
+
+
+
+
+
+status=open
+
+
+
+
+
+
+summary=be <cmmd> <argopt> --options doesn't raise GetOptions
+
+
+
+
+
+
+time=Thu, 27 Nov 2008 13:39:25 +0000
+
+
+
elif sys.argv[1] == '--commands':
for command, module in cmdutil.iter_commands():
print command
+elif sys.argv[1] == '--options':
+ print '\n'.join(cmdutil.options())
else:
try:
try:
except cmdutil.GetHelp:
print cmdutil.help(sys.argv[1])
sys.exit(0)
+ except cmdutil.GetCompletions, e:
+ print '\n'.join(e.completions)
+ sys.exit(0)
except cmdutil.UsageError, e:
print "Invalid usage:", e
print "\nArgs:", sys.argv[1:]
a:om: Bug A
b:cm: Bug B
"""
- options, args = get_parser().parse_args(args)
+ parser = get_parser()
+ options, args = parser.parse_args(args)
+
+ for option in [o.dest for o in parser.option_list if o.dest != None]:
+ value = getattr(options, option)
+ if value == "--options":
+ if option == "status":
+ raise cmdutil.GetCompletions(status_values)
+ raise cmdutil.GetCompletions()
+ if "--options" in args:
+ raise cmdutil.GetCompletions() # no completions for arguments yet
+
if len(args) > 0:
raise cmdutil.UsageError("Too many arguments.")
+
bd = bugdir.BugDir(from_disk=True, manipulate_encodings=not test)
bd.load_all_bugs()
# select status
--- /dev/null
+#!/bin/bash
+# Bash completion script for be (Bugs Everywhere)
+#
+# System wide installation:
+# Copy this file to /etc/bash_completion/be
+# Per-user installation:
+# Copy this file to ~/.be-completion.sh and source it in your .bashrc:
+# source ~/.be-completion.sh
+#
+# For a good intro to Bash completion, see Steve Kemp's article
+# "An introduction to bash completion: part 2"
+# http://www.debian-administration.org/articles/317
+
+# Support commands of the form:
+# be <command> [<long option>] [<long option>] ...
+# Requires:
+# be --commands
+# to print a list of available commands
+# be command [<option> ...] --options
+# to print a list of available long options
+_be()
+{
+ local cur prev opts
+ COMPREPLY=()
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
+
+ if [ $COMP_CWORD -eq 1 ]; then
+ # no command yet, show all commands
+ COMPREPLY=( $( compgen -W "$(be --commands)" -- $cur ) )
+ else
+ # remove the first word (should be "be") for security reasons
+ unset COMP_WORDS[0]
+ # remove the current word and all later words, because they
+ # are not needed for completion.
+ for i in `seq $COMP_CWORD ${#COMP_WORDS[@]}`; do
+ unset COMP_WORDS[$i];
+ done
+ COMPREPLY=( $( compgen -W "$(be "${COMP_WORDS[@]}" --options)" -- $cur ) )
+ fi
+}
+
+complete -F _be be
import os
from textwrap import TextWrapper
from StringIO import StringIO
+import sys
import doctest
import bugdir
UserError.__init__(self, str(exception))
self.exception = exception
-class GetHelp(Exception):
+class UsageError(Exception):
pass
-class UsageError(Exception):
+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"):
ret.append("be %s%*s %s" % (name, numExtraSpaces, "", desc))
return "\n".join(ret)
+def options(cmd=None):
+ if cmd != None:
+ parser = get_command(cmd).get_parser()
+ longopts = []
+ for opt in parser.option_list:
+ longopts.append(opt.get_opt_string())
+ return longopts
+ else:
+ # These probably shouldn't be hardcoded...
+ return ["--help","--commands","--options"]
+
def raise_get_help(option, opt, value, parser):
raise GetHelp
-
+
+def raise_get_completions(option, opt, value, parser):
+ raise GetCompletions(options(sys.argv[1]))
+
class CmdOptionParser(optparse.OptionParser):
def __init__(self, usage):
optparse.OptionParser.__init__(self, usage)
self.remove_option("-h")
self.add_option("-h", "--help", action="callback",
callback=raise_get_help, help="Print a help message")
+ self.add_option("--options", action="callback",
+ callback=raise_get_completions,
+ help="Print a list of available long options")
def error(self, message):
raise UsageError(message)