Skip to content

Commit

Permalink
Fixed issue where tab completion was quoting argparse flags in some c…
Browse files Browse the repository at this point in the history
…ases.
  • Loading branch information
kmvanbrunt committed Feb 16, 2022
1 parent 1050d99 commit 9676f8b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## 2.3.4 (TBD, 2021)
* Bug Fixes
* Fixed issue in `ansi.async_alert_str()` which would raise `IndexError` if prompt was blank.
* Fixed issue where tab completion was quoting argparse flags in some cases.
* Enhancements
* Added broader exception handling when enabling clipboard functionality via `pyperclip`.
* Added `PassThroughException` to `__init__.py` imports.
Expand Down
3 changes: 3 additions & 0 deletions cmd2/argparse_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,9 @@ def update_mutex_groups(arg_action: argparse.Action) -> None:
# 1. text is a single flag prefix character that didn't complete against any argument values
# 2. there are no more positionals to complete
if not skip_remaining_flags and (_single_prefix_char(text, self._parser) or not remaining_positionals):
# Reset any completion settings that may have been set by functions which actually had no matches.
# Otherwise, those settings could alter how the flags are displayed.
self._cmd2_app._reset_completion_defaults()
return self._complete_flags(text, line, begidx, endidx, matched_flags)

return completion_results
Expand Down
68 changes: 35 additions & 33 deletions cmd2/cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1498,11 +1498,6 @@ def path_complete(
# Used to complete ~ and ~user strings
def complete_users() -> List[str]:

# We are returning ~user strings that resolve to directories,
# so don't append a space or quote in the case of a single result.
self.allow_appended_space = False
self.allow_closing_quote = False

users = []

# Windows lacks the pwd module so we can't get a list of users.
Expand Down Expand Up @@ -1531,6 +1526,12 @@ def complete_users() -> List[str]:
cur_user += os.path.sep
users.append(cur_user)

if users:
# We are returning ~user strings that resolve to directories,
# so don't append a space or quote in the case of a single result.
self.allow_appended_space = False
self.allow_closing_quote = False

return users

# Determine if a trailing separator should be appended to directory completions
Expand Down Expand Up @@ -1581,47 +1582,48 @@ def complete_users() -> List[str]:
search_str = os.path.join(os.getcwd(), search_str)
cwd_added = True

# Set this to True for proper quoting of paths with spaces
self.matches_delimited = True

# Find all matching path completions
matches = glob.glob(search_str)

# Filter out results that don't belong
if path_filter is not None:
matches = [c for c in matches if path_filter(c)]

# Don't append a space or closing quote to directory
if len(matches) == 1 and os.path.isdir(matches[0]):
self.allow_appended_space = False
self.allow_closing_quote = False
if matches:
# Set this to True for proper quoting of paths with spaces
self.matches_delimited = True

# Don't append a space or closing quote to directory
if len(matches) == 1 and os.path.isdir(matches[0]):
self.allow_appended_space = False
self.allow_closing_quote = False

# Sort the matches before any trailing slashes are added
matches.sort(key=self.default_sort_key)
self.matches_sorted = True
# Sort the matches before any trailing slashes are added
matches.sort(key=self.default_sort_key)
self.matches_sorted = True

# Build display_matches and add a slash to directories
for index, cur_match in enumerate(matches):
# Build display_matches and add a slash to directories
for index, cur_match in enumerate(matches):

# Display only the basename of this path in the tab completion suggestions
self.display_matches.append(os.path.basename(cur_match))
# Display only the basename of this path in the tab completion suggestions
self.display_matches.append(os.path.basename(cur_match))

# Add a separator after directories if the next character isn't already a separator
if os.path.isdir(cur_match) and add_trailing_sep_if_dir:
matches[index] += os.path.sep
self.display_matches[index] += os.path.sep
# Add a separator after directories if the next character isn't already a separator
if os.path.isdir(cur_match) and add_trailing_sep_if_dir:
matches[index] += os.path.sep
self.display_matches[index] += os.path.sep

# Remove cwd if it was added to match the text readline expects
if cwd_added:
if cwd == os.path.sep:
to_replace = cwd
else:
to_replace = cwd + os.path.sep
matches = [cur_path.replace(to_replace, '', 1) for cur_path in matches]
# Remove cwd if it was added to match the text readline expects
if cwd_added:
if cwd == os.path.sep:
to_replace = cwd
else:
to_replace = cwd + os.path.sep
matches = [cur_path.replace(to_replace, '', 1) for cur_path in matches]

# Restore the tilde string if we expanded one to match the text readline expects
if expanded_tilde_path:
matches = [cur_path.replace(expanded_tilde_path, orig_tilde_path, 1) for cur_path in matches]
# Restore the tilde string if we expanded one to match the text readline expects
if expanded_tilde_path:
matches = [cur_path.replace(expanded_tilde_path, orig_tilde_path, 1) for cur_path in matches]

return matches

Expand Down

0 comments on commit 9676f8b

Please sign in to comment.