Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, these changes look good. You might consider modifying either the tab_completion.py or subcommands.py example to illustrate the case where this PR would matter.


# 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