From b2c8e2c819da74f5f77395aaa796b64678150635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20Nizio?= Date: Tue, 16 Jul 2019 08:35:32 +0200 Subject: [PATCH] [solo.commands.command] simplify and improve bash completions Note: below can mean double . This commit fixes cases such like the following ones: * crash (issue !73) - e.g. KeyError: u'--mtime': - equo security oscheck --mtime - equo query graph --complete (this was due to a typo in variable name) * now prints options, previously it didn't: - equo install -a * crashed, or (with only variable name fixed) didn't print all options: - equo security oscheck --mtime (note that it worked with more special -q instead of --mtime etc.) * didn't print all options: - equo query list installed (now shows also --by-user) The following behaviour is still buggy: * last typed word (note: no space before ) disappears upon completion: - equo security oscheck (not a regression) - equo install --deep (here it's an option; regression! - previously it didn't complete but didn't cause the word to be erased either) These can be corrected reliably when something like ${COMP_WORDS[COMP_CWORD]} (from complete -F) is passed to the Python side. Without this it's not possible to distinguish between `recognized_option` (completion of recognized_option) and `recognized_option `. --- client/solo/commands/command.py | 40 ++++++++++++--------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/client/solo/commands/command.py b/client/solo/commands/command.py index e81c0b29d..fbe831fb7 100644 --- a/client/solo/commands/command.py +++ b/client/solo/commands/command.py @@ -183,35 +183,23 @@ class SoloCommand(object): This method implements bash completion through a hierarchical (commands) dictionary object. """ - # navigate through commands, finding the list of commands _commands = commands - if not self._args: - # show all the commands - outcome += sorted(commands.keys()) - - for index, item in enumerate(self._args): - if item in _commands: - _commands = commands[item] - if index == (len(self._args) - 1): - # if this is the last one, generate - # proper outcome elements. - outcome += sorted(_commands.keys()) - # reset last_arg so that outcome list - # won't be filtered - last_arg = "" - elif index == (len(self._args) - 1): - # if this is the last one, and item - # is not in _commands, outcome becomes - # _commands.keys() - outcome += sorted(_commands.keys()) - # no need to break here - else: - # item not in commands, but that's not the - # last one, we must generate proper outcome - # elements and stop right after - outcome += sorted(_commands.keys()) + last_arg_recognised = False + for item in self._args: + if item not in _commands: + last_arg_recognised = False break + last_arg_recognised = True + if item.startswith("-"): + continue + _commands = _commands[item] + + outcome += sorted(_commands.keys()) + + if last_arg_recognised: + # Make it so all outcomes will be displayed, not filtered out. + last_arg = None return self._bashcomp(sys.stdout, last_arg, outcome)