diff --git a/README.rst b/README.rst index f9286b3..9ba202f 100644 --- a/README.rst +++ b/README.rst @@ -17,6 +17,13 @@ variable:: You'll find complete documentation on the shell by running ``surveil help``. +Bash completion +~~~~~~~~~~~~~~~ + +Basic command tab completion can be enabled by sourcing the bash completion script:: + + source /usr/local/share/monasca.bash_completion + Python API ---------- diff --git a/setup.cfg b/setup.cfg index 9678849..2fff20e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -7,6 +7,8 @@ description-file = [files] packages = surveilclient +data_files = + share = tools/surveil.bash_completion [entry_points] console_scripts = diff --git a/surveilclient/shell.py b/surveilclient/shell.py index d0bc765..eb9b629 100644 --- a/surveilclient/shell.py +++ b/surveilclient/shell.py @@ -62,8 +62,18 @@ class SurveilShell(object): submodule = utils.import_versioned_module(version, 'shell') self._find_actions(subparsers, submodule) self._find_actions(subparsers, self) + self._add_bash_completion_subparser(subparsers) return parser + def _add_bash_completion_subparser(self, subparsers): + subparser = subparsers.add_parser( + 'bash_completion', + add_help=False, + formatter_class=HelpFormatter + ) + self.subcommands['bash_completion'] = subparser + subparser.set_defaults(func=self.do_bash_completion) + def _find_actions(self, subparsers, actions_module): for attr in (a for a in dir(actions_module) if a.startswith('do_')): # I prefer to be hyphen-separated instead of underscores. @@ -99,6 +109,22 @@ class SurveilShell(object): else: self.parser.print_help() + def do_bash_completion(self, args): + """Prints all of the commands and options to stdout. + + The surveil.bash_completion script doesn't have to hard code them. + """ + commands = set() + options = set() + for sc_str, sc in self.subcommands.items(): + commands.add(sc_str) + for option in list(sc._optionals._option_string_actions): + options.add(option) + + commands.remove('bash-completion') + commands.remove('bash_completion') + print(' '.join(commands | options)) + def main(self, argv): # Parse args once to find version parser = self.get_base_parser() @@ -122,6 +148,9 @@ class SurveilShell(object): if args.func == self.do_help: self.do_help(args) return 0 + elif args.func == self.do_bash_completion: + self.do_bash_completion(args) + return 0 if not args.surveil_api_url: raise exc.CommandError("you must specify a Surveil API URL"