Skip to content

Commit

Permalink
Merge pull request #299 from python-cmd2/subcomplete
Browse files Browse the repository at this point in the history
Tweaked complete function to handle cases where a flag appears before…
  • Loading branch information
tleonhardt committed Mar 9, 2018
2 parents df2e4b7 + cf23503 commit f53005f
Showing 1 changed file with 39 additions and 32 deletions.
71 changes: 39 additions & 32 deletions cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def flag_based_complete(text, line, begidx, endidx, flag_dict, default_completer
return []

completions = []
flag_processed = False
flag_present = False

# Must have at least the command and one argument for a flag to be present
if len(tokens) > 1:
Expand All @@ -204,9 +204,10 @@ def flag_based_complete(text, line, begidx, endidx, flag_dict, default_completer
# Check if the flag is in the dictionary
if flag in flag_dict:

flag_present = True

# Check if this flag does completions using an Iterable
if isinstance(flag_dict[flag], collections.Iterable):
flag_processed = True
strs_to_match = flag_dict[flag]
completions = [cur_str for cur_str in strs_to_match if cur_str.startswith(text)]

Expand All @@ -216,12 +217,11 @@ def flag_based_complete(text, line, begidx, endidx, flag_dict, default_completer

# Otherwise check if this flag does completions with a function
elif callable(flag_dict[flag]):
flag_processed = True
completer_func = flag_dict[flag]
completions = completer_func(text, line, begidx, endidx)

# Check if we need to run the default completer
if default_completer is not None and not flag_processed:
if default_completer is not None and not flag_present:
completions = default_completer(text, line, begidx, endidx)

completions.sort()
Expand Down Expand Up @@ -254,34 +254,34 @@ def index_based_complete(text, line, begidx, endidx, index_dict, default_complet
# Invalid syntax for shlex (Probably due to missing closing quote)
return []

completions = []
if len(tokens) == 0:
return []

# Must have at least the command
if len(tokens) > 0:
completions = []

# Get the index of the token being completed
index = len(tokens)
# Get the index of the token being completed
index = len(tokens)

# Check if the index is in the dictionary
if index in index_dict:
# Check if the index is in the dictionary
if index in index_dict:

# Check if this index does completions using an Iterable
if isinstance(index_dict[index], collections.Iterable):
strs_to_match = index_dict[index]
completions = [cur_str for cur_str in strs_to_match if cur_str.startswith(text)]
# Check if this index does completions using an Iterable
if isinstance(index_dict[index], collections.Iterable):
strs_to_match = index_dict[index]
completions = [cur_str for cur_str in strs_to_match if cur_str.startswith(text)]

# If there is only 1 match and it's at the end of the line, then add a space
if len(completions) == 1 and endidx == len(line):
completions[0] += ' '
# If there is only 1 match and it's at the end of the line, then add a space
if len(completions) == 1 and endidx == len(line):
completions[0] += ' '

# Otherwise check if this index does completions with a function
elif callable(index_dict[index]):
completer_func = index_dict[index]
completions = completer_func(text, line, begidx, endidx)
# Otherwise check if this index does completions with a function
elif callable(index_dict[index]):
completer_func = index_dict[index]
completions = completer_func(text, line, begidx, endidx)

# Otherwise check if there is a default completer
elif default_completer is not None:
completions = default_completer(text, line, begidx, endidx)
# Otherwise check if there is a default completer
elif default_completer is not None:
completions = default_completer(text, line, begidx, endidx)

completions.sort()
return completions
Expand Down Expand Up @@ -1350,6 +1350,7 @@ def complete(self, text, state):
# Overwrite line to pass into completers
line = expanded_line

got_matches = False
if command == '':
compfunc = self.completedefault
else:
Expand All @@ -1361,16 +1362,22 @@ def complete(self, text, state):
compfunc = self.completedefault

# If there are subcommands, then try completing those if the cursor is in
# the correct position, otherwise default to using compfunc
# index 1 of the command tokens
subcommands = self.get_subcommands(command)
if subcommands is not None:
index_dict = {1: subcommands}
compfunc = functools.partial(index_based_complete,
index_dict=index_dict,
default_completer=compfunc)

# Call the completer function
self.completion_matches = compfunc(text, line, begidx, endidx)
tmp_matches = index_based_complete(text, line, begidx, endidx, index_dict)

# If we got sumcommand matches, then save them. Otherwise the cursor isn't in index 1
# or there is something else there like a flag. The command specific complete function
# will handle those cases.
if len(tmp_matches) > 0:
got_matches = True
self.completion_matches = tmp_matches

# Call the command specific completer function
if not got_matches:
self.completion_matches = compfunc(text, line, begidx, endidx)

else:
# Complete the command against command names and shortcuts. By design, shortcuts that start with
Expand Down

0 comments on commit f53005f

Please sign in to comment.