summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2022-02-16 13:16:36 -0500
committerKevin Van Brunt <kmvanbrunt@gmail.com>2022-02-16 13:30:39 -0500
commit9676f8bf6ad62175eb7c3f091c717d3dacaaf567 (patch)
tree648cbd001ffb547536d6f2796db9e9f1fcc0ef3d
parent1050d9933c2c46d948be0891b6b9a38ec7c1f3a2 (diff)
downloadcmd2-git-9676f8bf6ad62175eb7c3f091c717d3dacaaf567.tar.gz
Fixed issue where tab completion was quoting argparse flags in some cases.
-rw-r--r--CHANGELOG.md1
-rw-r--r--cmd2/argparse_completer.py3
-rw-r--r--cmd2/cmd2.py68
3 files changed, 39 insertions, 33 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 71089a1d..427be1e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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.
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py
index 9ec6677a..09ec2255 100644
--- a/cmd2/argparse_completer.py
+++ b/cmd2/argparse_completer.py
@@ -509,6 +509,9 @@ class ArgparseCompleter:
# 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
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index f6beb5d2..88e2492c 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -1498,11 +1498,6 @@ class Cmd(cmd.Cmd):
# 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.
@@ -1531,6 +1526,12 @@ class Cmd(cmd.Cmd):
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
@@ -1581,9 +1582,6 @@ class Cmd(cmd.Cmd):
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)
@@ -1591,37 +1589,41 @@ class Cmd(cmd.Cmd):
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