summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md8
-rwxr-xr-xREADME.md1
-rw-r--r--cmd2/argparse_completer.py68
-rw-r--r--cmd2/cmd2.py49
-rw-r--r--examples/transcripts/transcript_regex.txt1
-rw-r--r--tests/conftest.py2
-rw-r--r--tests/test_argparse_completer.py104
-rw-r--r--tests/transcripts/regex_set.txt1
8 files changed, 156 insertions, 78 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a78f00c1..5ef17000 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,14 @@
See [read_input.py](https://github.com/python-cmd2/cmd2/blob/master/examples/read_input.py)
for an example.
+## 1.4.0 (TBD, 2020)
+* Enhancements
+ * Added user-settable option called `always_show_hint`. If True, then tab completion hints will always
+ display even when tab completion suggestions print. Arguments whose help or hint text is suppressed will
+ not display hints even when this setting is True.
+* Bug Fixes
+ * Fixed issue where flag names weren't always sorted correctly in argparse tab completion
+
## 1.3.9 (September 03, 2020)
* Breaking Changes
* `CommandSet.on_unregister()` is now called as first step in unregistering a `CommandSet` and not
diff --git a/README.md b/README.md
index ca03cc47..8bb8b930 100755
--- a/README.md
+++ b/README.md
@@ -322,6 +322,7 @@ example/transcript_regex.txt:
# regexes on prompts just make the trailing space obvious
(Cmd) set
allow_style: '/(Terminal|Always|Never)/'
+always_show_hint: False
debug: False
echo: False
editor: /.*?/
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py
index 39e9607b..535caf88 100644
--- a/cmd2/argparse_completer.py
+++ b/cmd2/argparse_completer.py
@@ -35,6 +35,22 @@ DEFAULT_DESCRIPTIVE_HEADER = 'Description'
ARG_TOKENS = 'arg_tokens'
+# noinspection PyProtectedMember
+def _build_hint(parser: argparse.ArgumentParser, arg_action: argparse.Action) -> str:
+ """Build tab completion hint for a given argument"""
+ # Check if hinting is disabled for this argument
+ suppress_hint = getattr(arg_action, ATTR_SUPPRESS_TAB_HINT, False)
+ if suppress_hint or arg_action.help == argparse.SUPPRESS:
+ return ''
+ else:
+ # Use the parser's help formatter to display just this action's help text
+ formatter = parser._get_formatter()
+ formatter.start_section("Hint")
+ formatter.add_argument(arg_action)
+ formatter.end_section()
+ return formatter.format_help()
+
+
def _single_prefix_char(token: str, parser: argparse.ArgumentParser) -> bool:
"""Returns if a token is just a single flag prefix character"""
return len(token) == 1 and token[0] in parser.prefix_chars
@@ -115,7 +131,6 @@ class _UnfinishedFlagError(CompletionError):
super().__init__(error)
-# noinspection PyProtectedMember
class _NoResultsError(CompletionError):
def __init__(self, parser: argparse.ArgumentParser, arg_action: argparse.Action) -> None:
"""
@@ -124,19 +139,8 @@ class _NoResultsError(CompletionError):
:param parser: ArgumentParser instance which owns the action being tab completed
:param arg_action: action being tab completed
"""
- # Check if hinting is disabled
- suppress_hint = getattr(arg_action, ATTR_SUPPRESS_TAB_HINT, False)
- if suppress_hint or arg_action.help == argparse.SUPPRESS:
- hint_str = ''
- else:
- # Use the parser's help formatter to print just this action's help text
- formatter = parser._get_formatter()
- formatter.start_section("Hint")
- formatter.add_argument(arg_action)
- formatter.end_section()
- hint_str = formatter.format_help()
# Set apply_style to False because we don't want hints to look like errors
- super().__init__(hint_str, apply_style=False)
+ super().__init__(_build_hint(parser, arg_action), apply_style=False)
# noinspection PyProtectedMember
@@ -419,6 +423,7 @@ class ArgparseCompleter:
# If we have results, then return them
if completion_results:
+ self._cmd2_app.completion_hint = _build_hint(self._parser, flag_arg_state.action)
return completion_results
# Otherwise, print a hint if the flag isn't finished or text isn't possibly the start of a flag
@@ -439,6 +444,7 @@ class ArgparseCompleter:
# If we have results, then return them
if completion_results:
+ self._cmd2_app.completion_hint = _build_hint(self._parser, pos_arg_state.action)
return completion_results
# Otherwise, print a hint if text isn't possibly the start of a flag
@@ -572,12 +578,21 @@ class ArgparseCompleter:
"""
# Check if the arg provides choices to the user
if arg_state.action.choices is not None:
- arg_choices = arg_state.action.choices
+ arg_choices = list(arg_state.action.choices)
+ if not arg_choices:
+ return []
+
+ # If these choices are numbers, then sort them now
+ if all(isinstance(x, numbers.Number) for x in arg_choices):
+ arg_choices.sort()
+ self._cmd2_app.matches_sorted = True
+
+ # Since choices can be various types, convert them all to strings
+ arg_choices = [str(x) for x in arg_choices]
else:
arg_choices = getattr(arg_state.action, ATTR_CHOICES_CALLABLE, None)
-
- if arg_choices is None:
- return []
+ if arg_choices is None:
+ return []
# If we are going to call a completer/choices function, then set up the common arguments
args = []
@@ -617,19 +632,6 @@ class ArgparseCompleter:
if isinstance(arg_choices, ChoicesCallable) and not arg_choices.is_completer:
arg_choices = arg_choices.to_call(*args, **kwargs)
- # Since arg_choices can be any iterable type, convert to a list
- arg_choices = list(arg_choices)
-
- # If these choices are numbers, and have not yet been sorted, then sort them now
- if not self._cmd2_app.matches_sorted and all(isinstance(x, numbers.Number) for x in arg_choices):
- arg_choices.sort()
- self._cmd2_app.matches_sorted = True
-
- # Since choices can be various types like int, we must convert them to strings
- for index, choice in enumerate(arg_choices):
- if not isinstance(choice, str):
- arg_choices[index] = str(choice)
-
# Filter out arguments we already used
used_values = consumed_arg_values.get(arg_state.action.dest, [])
arg_choices = [choice for choice in arg_choices if choice not in used_values]
@@ -637,4 +639,10 @@ class ArgparseCompleter:
# Do tab completion on the choices
results = self._cmd2_app.basic_complete(text, line, begidx, endidx, arg_choices)
+ if not results:
+ # Reset the value for matches_sorted. This is because completion of flag names
+ # may still be attempted after we return and they haven't been sorted yet.
+ self._cmd2_app.matches_sorted = False
+ return []
+
return self._format_completions(arg_state, results)
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index a8a84499..088bb500 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -244,6 +244,7 @@ class Cmd(cmd.Cmd):
self.allow_redirection = allow_redirection # Security setting to prevent redirection of stdout
# Attributes which ARE dynamically settable via the set command at runtime
+ self.always_show_hint = False
self.debug = False
self.echo = False
self.editor = Cmd.DEFAULT_EDITOR
@@ -411,17 +412,21 @@ class Cmd(cmd.Cmd):
# will be added if there is an unmatched opening quote
self.allow_closing_quote = True
- # An optional header that prints above the tab completion suggestions
+ # An optional hint which prints above tab completion suggestions
+ self.completion_hint = ''
+
+ # Header which prints above CompletionItem tables
self.completion_header = ''
# Used by complete() for readline tab completion
self.completion_matches = []
- # Use this list if you are completing strings that contain a common delimiter and you only want to
- # display the final portion of the matches as the tab completion suggestions. The full matches
- # still must be returned from your completer function. For an example, look at path_complete()
- # which uses this to show only the basename of paths as the suggestions. delimiter_complete() also
- # populates this list.
+ # Use this list if you need to display tab completion suggestions that are different than the actual text
+ # of the matches. For instance, if you are completing strings that contain a common delimiter and you only
+ # want to display the final portion of the matches as the tab completion suggestions. The full matches
+ # still must be returned from your completer function. For an example, look at path_complete() which
+ # uses this to show only the basename of paths as the suggestions. delimiter_complete() also populates
+ # this list.
self.display_matches = []
# Used by functions like path_complete() and delimiter_complete() to properly
@@ -824,6 +829,8 @@ class Cmd(cmd.Cmd):
ansi.STYLE_NEVER),
choices=[ansi.STYLE_TERMINAL, ansi.STYLE_ALWAYS, ansi.STYLE_NEVER]))
+ self.add_settable(Settable('always_show_hint', bool,
+ 'Display tab completion hint even when completion suggestions print'))
self.add_settable(Settable('debug', bool, "Show full traceback on exception"))
self.add_settable(Settable('echo', bool, "Echo command issued into output"))
self.add_settable(Settable('editor', str, "Program used by 'edit'"))
@@ -1020,6 +1027,7 @@ class Cmd(cmd.Cmd):
"""
self.allow_appended_space = True
self.allow_closing_quote = True
+ self.completion_hint = ''
self.completion_header = ''
self.completion_matches = []
self.display_matches = []
@@ -1530,6 +1538,22 @@ class Cmd(cmd.Cmd):
return [cur_match + padding for cur_match in matches_to_display], len(padding)
+ def _build_completion_metadata_string(self) -> str: # pragma: no cover
+ """Build completion metadata string which can contain a hint and CompletionItem table header"""
+ metadata = ''
+
+ # Add hint if one exists and we are supposed to display it
+ if self.always_show_hint and self.completion_hint:
+ metadata += '\n' + self.completion_hint
+
+ # Add table header if one exists
+ if self.completion_header:
+ if not metadata:
+ metadata += '\n'
+ metadata += '\n' + self.completion_header
+
+ return metadata
+
def _display_matches_gnu_readline(self, substitution: str, matches: List[str],
longest_match_length: int) -> None: # pragma: no cover
"""Prints a match list using GNU readline's rl_display_match_list()
@@ -1574,9 +1598,8 @@ class Cmd(cmd.Cmd):
strings_array[1:-1] = encoded_matches
strings_array[-1] = None
- # Print the header if one exists
- if self.completion_header:
- sys.stdout.write('\n\n' + self.completion_header)
+ # Print any metadata like a hint or table header
+ sys.stdout.write(self._build_completion_metadata_string())
# Call readline's display function
# rl_display_match_list(strings_array, number of completion matches, longest match length)
@@ -1602,10 +1625,8 @@ class Cmd(cmd.Cmd):
# Add padding for visual appeal
matches_to_display, _ = self._pad_matches_to_display(matches_to_display)
- # Print the header if one exists
- if self.completion_header:
- # noinspection PyUnresolvedReferences
- readline.rl.mode.console.write('\n\n' + self.completion_header)
+ # Print any metadata like a hint or table header
+ readline.rl.mode.console.write(sys.stdout.write(self._build_completion_metadata_string()))
# Display matches using actual display function. This also redraws the prompt and line.
orig_pyreadline_display(matches_to_display)
@@ -3433,7 +3454,7 @@ class Cmd(cmd.Cmd):
# Create the parser for the set command
set_parser = DEFAULT_ARGUMENT_PARSER(parents=[set_parser_parent])
set_parser.add_argument('value', nargs=argparse.OPTIONAL, help='new value for settable',
- completer=complete_set_value)
+ completer=complete_set_value, suppress_tab_hint=True)
# Preserve quotes so users can pass in quoted empty strings and flags (e.g. -h) as the value
@with_argparser(set_parser, preserve_quotes=True)
diff --git a/examples/transcripts/transcript_regex.txt b/examples/transcripts/transcript_regex.txt
index a3a91236..3065aae5 100644
--- a/examples/transcripts/transcript_regex.txt
+++ b/examples/transcripts/transcript_regex.txt
@@ -4,6 +4,7 @@
# regexes on prompts just make the trailing space obvious
(Cmd) set
allow_style: '/(Terminal|Always|Never)/'
+always_show_hint: False
debug: False
echo: False
editor: /.*?/
diff --git a/tests/conftest.py b/tests/conftest.py
index 5b1a6f05..73080b5c 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -93,6 +93,7 @@ SHORTCUTS_TXT = """Shortcuts for other commands:
# Output from the show command with default settings
SHOW_TXT = """allow_style: 'Terminal'
+always_show_hint: False
debug: False
echo: False
editor: 'vim'
@@ -104,6 +105,7 @@ timing: False
SHOW_LONG = """
allow_style: 'Terminal' # Allow ANSI text style sequences in output (valid values: Terminal, Always, Never)
+always_show_hint: False # Display tab completion hint even when completion suggestions print
debug: False # Show full traceback on exception
echo: False # Echo command issued into output
editor: 'vim' # Program used by 'edit'
diff --git a/tests/test_argparse_completer.py b/tests/test_argparse_completer.py
index b63511cd..3ee9766e 100644
--- a/tests/test_argparse_completer.py
+++ b/tests/test_argparse_completer.py
@@ -4,6 +4,7 @@
Unit/functional testing for argparse completer in cmd2
"""
import argparse
+import numbers
from typing import List
import pytest
@@ -28,7 +29,7 @@ def standalone_completer(cli: cmd2.Cmd, text: str, line: str, begidx: int, endid
# noinspection PyMethodMayBeStatic,PyUnusedLocal,PyProtectedMember
-class AutoCompleteTester(cmd2.Cmd):
+class ArgparseCompleterTester(cmd2.Cmd):
"""Cmd2 app that exercises ArgparseCompleter class"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -84,7 +85,9 @@ class AutoCompleteTester(cmd2.Cmd):
TUPLE_METAVAR = ('arg1', 'others')
CUSTOM_DESC_HEADER = "Custom Header"
- static_int_choices_list = [-1, 1, -2, 2, 0, -12]
+ # Lists used in our tests (there is a mix of sorted and unsorted on purpose)
+ non_negative_int_choices = [1, 2, 3, 0, 22]
+ int_choices = [-1, 1, -2, 2, 0, -12]
static_choices_list = ['static', 'choices', 'stop', 'here']
choices_from_provider = ['choices', 'provider', 'probably', 'improved']
@@ -116,13 +119,17 @@ class AutoCompleteTester(cmd2.Cmd):
choices_provider=completion_item_method, metavar=TUPLE_METAVAR,
nargs=argparse.ONE_OR_MORE)
choices_parser.add_argument('-i', '--int', type=int, help='a flag with an int type',
- choices=static_int_choices_list)
+ choices=int_choices)
# Positional args for choices command
choices_parser.add_argument("list_pos", help="a positional populated with a choices list",
choices=static_choices_list)
choices_parser.add_argument("method_pos", help="a positional populated with a choices provider",
choices_provider=choices_provider)
+ choices_parser.add_argument('non_negative_int', type=int, help='a positional with non-negative int choices',
+ choices=non_negative_int_choices)
+ choices_parser.add_argument('empty_choices', help='a positional with empty choices',
+ choices=[])
@with_argparser(choices_parser)
def do_choices(self, args: argparse.Namespace) -> None:
@@ -290,7 +297,7 @@ class AutoCompleteTester(cmd2.Cmd):
@pytest.fixture
def ac_app():
- app = AutoCompleteTester()
+ app = ArgparseCompleterTester()
app.stdout = StdSim(app.stdout)
return app
@@ -417,18 +424,16 @@ def test_autcomp_flag_completion(ac_app, command_and_args, text, completions):
@pytest.mark.parametrize('flag, text, completions', [
- ('-l', '', AutoCompleteTester.static_choices_list),
+ ('-l', '', ArgparseCompleterTester.static_choices_list),
('--list', 's', ['static', 'stop']),
- ('-p', '', AutoCompleteTester.choices_from_provider),
+ ('-p', '', ArgparseCompleterTester.choices_from_provider),
('--provider', 'pr', ['provider', 'probably']),
- ('-i', '', AutoCompleteTester.static_int_choices_list),
+ ('-i', '', ArgparseCompleterTester.int_choices),
('--int', '1', ['1 ']),
('--int', '-', [-1, -2, -12]),
('--int', '-1', [-1, -12])
])
def test_autocomp_flag_choices_completion(ac_app, flag, text, completions):
- import numbers
-
line = 'choices {} {}'.format(flag, text)
endidx = len(line)
begidx = endidx - len(text)
@@ -440,7 +445,7 @@ def test_autocomp_flag_choices_completion(ac_app, flag, text, completions):
assert first_match is None
# Numbers will be sorted in ascending order and then converted to strings by ArgparseCompleter
- if all(isinstance(x, numbers.Number) for x in completions):
+ if completions and all(isinstance(x, numbers.Number) for x in completions):
completions.sort()
completions = [str(x) for x in completions]
else:
@@ -450,10 +455,13 @@ def test_autocomp_flag_choices_completion(ac_app, flag, text, completions):
@pytest.mark.parametrize('pos, text, completions', [
- (1, '', AutoCompleteTester.static_choices_list),
+ (1, '', ArgparseCompleterTester.static_choices_list),
(1, 's', ['static', 'stop']),
- (2, '', AutoCompleteTester.choices_from_provider),
+ (2, '', ArgparseCompleterTester.choices_from_provider),
(2, 'pr', ['provider', 'probably']),
+ (3, '', ArgparseCompleterTester.non_negative_int_choices),
+ (3, '2', [2, 22]),
+ (4, '', []),
])
def test_autocomp_positional_choices_completion(ac_app, pos, text, completions):
# Generate line were preceding positionals are already filled
@@ -467,11 +475,39 @@ def test_autocomp_positional_choices_completion(ac_app, pos, text, completions):
else:
assert first_match is None
- assert ac_app.completion_matches == sorted(completions, key=ac_app.default_sort_key)
+ # Numbers will be sorted in ascending order and then converted to strings by ArgparseCompleter
+ if completions and all(isinstance(x, numbers.Number) for x in completions):
+ completions.sort()
+ completions = [str(x) for x in completions]
+ else:
+ completions.sort(key=ac_app.default_sort_key)
+
+ assert ac_app.completion_matches == completions
+
+
+def test_flag_sorting(ac_app):
+ # This test exercises the case where a positional arg has non-negative integers for its choices.
+ # ArgparseCompleter will sort these numerically before converting them to strings. As a result,
+ # cmd2.matches_sorted gets set to True. If no completion matches are returned and the entered
+ # text looks like the beginning of a flag (e.g -), then ArgparseCompleter will try to complete
+ # flag names next. Before it does this, cmd2.matches_sorted is reset to make sure the flag names
+ # get sorted correctly.
+ option_strings = []
+ for action in ac_app.choices_parser._actions:
+ option_strings.extend(action.option_strings)
+ option_strings.sort(key=ac_app.default_sort_key)
+
+ text = '-'
+ line = 'choices arg1 arg2 arg3 {}'.format(text)
+ endidx = len(line)
+ begidx = endidx - len(text)
+
+ first_match = complete_tester(text, line, begidx, endidx, ac_app)
+ assert first_match is not None and ac_app.completion_matches == option_strings
@pytest.mark.parametrize('flag, text, completions', [
- ('-c', '', AutoCompleteTester.completions_for_flag),
+ ('-c', '', ArgparseCompleterTester.completions_for_flag),
('--completer', 'f', ['flag', 'fairly'])
])
def test_autocomp_flag_completers(ac_app, flag, text, completions):
@@ -489,9 +525,9 @@ def test_autocomp_flag_completers(ac_app, flag, text, completions):
@pytest.mark.parametrize('pos, text, completions', [
- (1, '', AutoCompleteTester.completions_for_pos_1),
+ (1, '', ArgparseCompleterTester.completions_for_pos_1),
(1, 'p', ['positional_1', 'probably']),
- (2, '', AutoCompleteTester.completions_for_pos_2),
+ (2, '', ArgparseCompleterTester.completions_for_pos_2),
(2, 'm', ['missed', 'me']),
])
def test_autocomp_positional_completers(ac_app, pos, text, completions):
@@ -524,7 +560,7 @@ def test_autocomp_blank_token(ac_app):
completer = ArgparseCompleter(ac_app.completer_parser, ac_app)
tokens = ['-c', blank, text]
completions = completer.complete(text, line, begidx, endidx, tokens)
- assert sorted(completions) == sorted(AutoCompleteTester.completions_for_pos_1)
+ assert sorted(completions) == sorted(ArgparseCompleterTester.completions_for_pos_1)
# Blank arg for first positional will be consumed. Therefore we expect to be completing the second positional.
text = ''
@@ -535,7 +571,7 @@ def test_autocomp_blank_token(ac_app):
completer = ArgparseCompleter(ac_app.completer_parser, ac_app)
tokens = [blank, text]
completions = completer.complete(text, line, begidx, endidx, tokens)
- assert sorted(completions) == sorted(AutoCompleteTester.completions_for_pos_2)
+ assert sorted(completions) == sorted(ArgparseCompleterTester.completions_for_pos_2)
@pytest.mark.parametrize('num_aliases, show_description', [
@@ -569,54 +605,54 @@ def test_completion_items(ac_app, num_aliases, show_description):
@pytest.mark.parametrize('args, completions', [
# Flag with nargs = 2
- ('--set_value', AutoCompleteTester.set_value_choices),
+ ('--set_value', ArgparseCompleterTester.set_value_choices),
('--set_value set', ['value', 'choices']),
# Both args are filled. At positional arg now.
- ('--set_value set value', AutoCompleteTester.positional_choices),
+ ('--set_value set value', ArgparseCompleterTester.positional_choices),
# Using the flag again will reset the choices available
- ('--set_value set value --set_value', AutoCompleteTester.set_value_choices),
+ ('--set_value set value --set_value', ArgparseCompleterTester.set_value_choices),
# Flag with nargs = ONE_OR_MORE
- ('--one_or_more', AutoCompleteTester.one_or_more_choices),
+ ('--one_or_more', ArgparseCompleterTester.one_or_more_choices),
('--one_or_more one', ['or', 'more', 'choices']),
# Flag with nargs = OPTIONAL
- ('--optional', AutoCompleteTester.optional_choices),
+ ('--optional', ArgparseCompleterTester.optional_choices),
# Only one arg allowed for an OPTIONAL. At positional now.
- ('--optional optional', AutoCompleteTester.positional_choices),
+ ('--optional optional', ArgparseCompleterTester.positional_choices),
# Flag with nargs range (1, 2)
- ('--range', AutoCompleteTester.range_choices),
+ ('--range', ArgparseCompleterTester.range_choices),
('--range some', ['range', 'choices']),
# Already used 2 args so at positional
- ('--range some range', AutoCompleteTester.positional_choices),
+ ('--range some range', ArgparseCompleterTester.positional_choices),
# Flag with nargs = REMAINDER
- ('--remainder', AutoCompleteTester.remainder_choices),
+ ('--remainder', ArgparseCompleterTester.remainder_choices),
('--remainder remainder ', ['choices ']),
# No more flags can appear after a REMAINDER flag)
('--remainder choices --set_value', ['remainder ']),
# Double dash ends the current flag
- ('--range choice --', AutoCompleteTester.positional_choices),
+ ('--range choice --', ArgparseCompleterTester.positional_choices),
# Double dash ends a REMAINDER flag
- ('--remainder remainder --', AutoCompleteTester.positional_choices),
+ ('--remainder remainder --', ArgparseCompleterTester.positional_choices),
# No more flags after a double dash
- ('-- --one_or_more ', AutoCompleteTester.positional_choices),
+ ('-- --one_or_more ', ArgparseCompleterTester.positional_choices),
# Consume positional
- ('', AutoCompleteTester.positional_choices),
+ ('', ArgparseCompleterTester.positional_choices),
('positional', ['the', 'choices']),
# Intermixed flag and positional
- ('positional --set_value', AutoCompleteTester.set_value_choices),
+ ('positional --set_value', ArgparseCompleterTester.set_value_choices),
('positional --set_value set', ['choices', 'value']),
# Intermixed flag and positional with flag finishing
@@ -624,12 +660,12 @@ def test_completion_items(ac_app, num_aliases, show_description):
('positional --range choice --', ['the', 'choices']),
# REMAINDER positional
- ('the positional', AutoCompleteTester.remainder_choices),
+ ('the positional', ArgparseCompleterTester.remainder_choices),
('the positional remainder', ['choices ']),
('the positional remainder choices', []),
# REMAINDER positional. Flags don't work in REMAINDER
- ('the positional --set_value', AutoCompleteTester.remainder_choices),
+ ('the positional --set_value', ArgparseCompleterTester.remainder_choices),
('the positional remainder --set_value', ['choices '])
])
def test_autcomp_nargs(ac_app, args, completions):
diff --git a/tests/transcripts/regex_set.txt b/tests/transcripts/regex_set.txt
index 5004adc5..623df8ed 100644
--- a/tests/transcripts/regex_set.txt
+++ b/tests/transcripts/regex_set.txt
@@ -5,6 +5,7 @@
(Cmd) set
allow_style: /'(Terminal|Always|Never)'/
+always_show_hint: False
debug: False
echo: False
editor: /'.*'/