Skip to content

Commit 9676f8b

Browse files
committed
Fixed issue where tab completion was quoting argparse flags in some cases.
1 parent 1050d99 commit 9676f8b

File tree

3 files changed

+39
-33
lines changed

3 files changed

+39
-33
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## 2.3.4 (TBD, 2021)
22
* Bug Fixes
33
* Fixed issue in `ansi.async_alert_str()` which would raise `IndexError` if prompt was blank.
4+
* Fixed issue where tab completion was quoting argparse flags in some cases.
45
* Enhancements
56
* Added broader exception handling when enabling clipboard functionality via `pyperclip`.
67
* Added `PassThroughException` to `__init__.py` imports.

cmd2/argparse_completer.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,9 @@ def update_mutex_groups(arg_action: argparse.Action) -> None:
509509
# 1. text is a single flag prefix character that didn't complete against any argument values
510510
# 2. there are no more positionals to complete
511511
if not skip_remaining_flags and (_single_prefix_char(text, self._parser) or not remaining_positionals):
512+
# Reset any completion settings that may have been set by functions which actually had no matches.
513+
# Otherwise, those settings could alter how the flags are displayed.
514+
self._cmd2_app._reset_completion_defaults()
512515
return self._complete_flags(text, line, begidx, endidx, matched_flags)
513516

514517
return completion_results

cmd2/cmd2.py

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,11 +1498,6 @@ def path_complete(
14981498
# Used to complete ~ and ~user strings
14991499
def complete_users() -> List[str]:
15001500

1501-
# We are returning ~user strings that resolve to directories,
1502-
# so don't append a space or quote in the case of a single result.
1503-
self.allow_appended_space = False
1504-
self.allow_closing_quote = False
1505-
15061501
users = []
15071502

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

1529+
if users:
1530+
# We are returning ~user strings that resolve to directories,
1531+
# so don't append a space or quote in the case of a single result.
1532+
self.allow_appended_space = False
1533+
self.allow_closing_quote = False
1534+
15341535
return users
15351536

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

1584-
# Set this to True for proper quoting of paths with spaces
1585-
self.matches_delimited = True
1586-
15871585
# Find all matching path completions
15881586
matches = glob.glob(search_str)
15891587

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

1594-
# Don't append a space or closing quote to directory
1595-
if len(matches) == 1 and os.path.isdir(matches[0]):
1596-
self.allow_appended_space = False
1597-
self.allow_closing_quote = False
1592+
if matches:
1593+
# Set this to True for proper quoting of paths with spaces
1594+
self.matches_delimited = True
1595+
1596+
# Don't append a space or closing quote to directory
1597+
if len(matches) == 1 and os.path.isdir(matches[0]):
1598+
self.allow_appended_space = False
1599+
self.allow_closing_quote = False
15981600

1599-
# Sort the matches before any trailing slashes are added
1600-
matches.sort(key=self.default_sort_key)
1601-
self.matches_sorted = True
1601+
# Sort the matches before any trailing slashes are added
1602+
matches.sort(key=self.default_sort_key)
1603+
self.matches_sorted = True
16021604

1603-
# Build display_matches and add a slash to directories
1604-
for index, cur_match in enumerate(matches):
1605+
# Build display_matches and add a slash to directories
1606+
for index, cur_match in enumerate(matches):
16051607

1606-
# Display only the basename of this path in the tab completion suggestions
1607-
self.display_matches.append(os.path.basename(cur_match))
1608+
# Display only the basename of this path in the tab completion suggestions
1609+
self.display_matches.append(os.path.basename(cur_match))
16081610

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

1614-
# Remove cwd if it was added to match the text readline expects
1615-
if cwd_added:
1616-
if cwd == os.path.sep:
1617-
to_replace = cwd
1618-
else:
1619-
to_replace = cwd + os.path.sep
1620-
matches = [cur_path.replace(to_replace, '', 1) for cur_path in matches]
1616+
# Remove cwd if it was added to match the text readline expects
1617+
if cwd_added:
1618+
if cwd == os.path.sep:
1619+
to_replace = cwd
1620+
else:
1621+
to_replace = cwd + os.path.sep
1622+
matches = [cur_path.replace(to_replace, '', 1) for cur_path in matches]
16211623

1622-
# Restore the tilde string if we expanded one to match the text readline expects
1623-
if expanded_tilde_path:
1624-
matches = [cur_path.replace(expanded_tilde_path, orig_tilde_path, 1) for cur_path in matches]
1624+
# Restore the tilde string if we expanded one to match the text readline expects
1625+
if expanded_tilde_path:
1626+
matches = [cur_path.replace(expanded_tilde_path, orig_tilde_path, 1) for cur_path in matches]
16251627

16261628
return matches
16271629

0 commit comments

Comments
 (0)