diff options
author | Patrick Totzke <patricktotzke@gmail.com> | 2012-01-17 19:29:03 +0000 |
---|---|---|
committer | Patrick Totzke <patricktotzke@gmail.com> | 2012-01-20 12:41:58 +0000 |
commit | 8afcb1cf2313cd19499feadb2f61cad23694e1e0 (patch) | |
tree | 1d01a54ba124eb5860639b686930b3a079b330d4 /alot/completion.py | |
parent | b9ffa4b1c00685962fca6aa6cf7ca84ecadf9c69 (diff) |
completion for argparse optional parameters
This introduces an ArgparseOptionCompleter that completes
option strings for a given argparse.Parser.
These are used in CommandlineParsers initially.
issue #162
Diffstat (limited to 'alot/completion.py')
-rw-r--r-- | alot/completion.py | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/alot/completion.py b/alot/completion.py index 8e474691..99027ab2 100644 --- a/alot/completion.py +++ b/alot/completion.py @@ -2,6 +2,7 @@ import re import os import glob import logging +import argparse import alot.commands as commands from alot.buffers import EnvelopeBuffer @@ -207,6 +208,36 @@ class AbooksCompleter(Completer): returnlist.append((newtext, len(newtext))) return returnlist +class ArgparseOptionCompleter(Completer): + """completes option parameters for a given argparse.Parser""" + def __init__(self, parser): + """ + :param parser: the option parser we look up parameter and choices from + :type parser: `argparse.ArgumentParser` + """ + self.parser = parser + self.actions = parser._optionals._actions + + def complete(self, original, pos): + pref = original[:pos] + + res = [] + for act in self.actions: + if '=' in pref: + optionstring = pref[:pref.rfind('=')+1] + # get choices + if 'choices' in act.__dict__: + choices = act.choices or [] + res = res + [optionstring + a for a in choices] + else: + for optionstring in act.option_strings: + if optionstring.startswith(pref): + # append '=' for options that await a string value + if isinstance(act, argparse._StoreAction): + optionstring += '=' + res.append(optionstring) + + return [(a, len(a)) for a in res] class AccountCompleter(StringlistCompleter): """completes users' own mailaddresses""" @@ -279,11 +310,33 @@ class CommandLineCompleter(Completer): else: cmd, params = words localpos = pos - (len(cmd) + 1) + parser = commands.lookup_parser(cmd, self.mode) # set 'res' - the result set of matching completionstrings # depending on the current mode and command + # detect if we are completing optional parameter + arguments_until_now = params[:localpos].split(' ') + all_optionals = True + logging.debug(str(arguments_until_now)) + for a in arguments_until_now: + logging.debug(a) + if a and not a.startswith('-'): + all_optionals = False + # complete optional parameter if + # 1. all arguments prior to current position are optional parameter + # 2. the parameter starts with '-' or we are at its beginning + if all_optionals: + myarg = arguments_until_now[-1] + start_myarg = params.rindex(myarg) + beforeme = params[:start_myarg] + # set up local stringlist completer + # and let it complete for given list of options + localcompleter = ArgparseOptionCompleter(parser) + localres = localcompleter.complete(myarg, len(myarg)) + res = [(beforeme + c, p + start_myarg) for (c, p) in localres] + # global - if cmd == 'search': + elif cmd == 'search': res = self._querycompleter.complete(params, localpos) elif cmd == 'help': res = self._commandcompleter.complete(params, localpos) |