Skip to content

Instantly share code, notes, and snippets.

@0xa
Created October 25, 2015 16:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xa/d92376452b6f858a978e to your computer and use it in GitHub Desktop.
Save 0xa/d92376452b6f858a978e to your computer and use it in GitHub Desktop.
class Completer:
def __init__(self, commands):
self.commands = commands
self.completed = None
for name, c in self.commands.items():
c._comp_positionals = len([a for a in c.parser._actions
if not a.option_strings])
def complete_cmd(self, command_name, argv):
argv_wos = [a for a in argv if a]
command = self.commands[command_name]
if len(argv_wos) < command._comp_positionals:
# Cannot complete positionals
return []
arg = argv[-1] if argv else '' # the one we want to complete
prev = argv[-2] if len(argv) > 1 else '' # the one before
actions = command.parser._option_string_actions
if prev in actions and isinstance(actions[prev], argparse._StoreAction):
# Expecting a value
return []
options = actions.keys()
base = ' '.join(argv[:-1]) + ' '
return [base + k for k in options if k.startswith(arg)]
def complete(self, text, state=0):
if self.completed != text:
sl = text.split(' ')
cmd, argv = sl[0], sl[1:]
if cmd in self.commands:
self.matches = [cmd + ' ' + c for c in self.complete_cmd(cmd, argv)]
else:
self.matches = [c for c in self.commands.keys()
if c.startswith(cmd)]
self.completed = text
if not self.matches:
return None
return self.matches[state]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment