diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/click/core.py | 3 | ||||
-rw-r--r-- | src/click/shell_completion.py | 17 |
2 files changed, 11 insertions, 9 deletions
diff --git a/src/click/core.py b/src/click/core.py index 263a5ff..939ad81 100644 --- a/src/click/core.py +++ b/src/click/core.py @@ -292,6 +292,8 @@ class Context: #: must be never propagated to another arguments. This is used #: to implement nested parsing. self.protected_args: t.List[str] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() if obj is None and parent is not None: obj = parent.obj @@ -1385,6 +1387,7 @@ class Command(BaseCommand): ) ctx.args = args + ctx._opt_prefixes.update(parser._opt_prefixes) return args def invoke(self, ctx: Context) -> t.Any: diff --git a/src/click/shell_completion.py b/src/click/shell_completion.py index 1e9df6f..c17a8e6 100644 --- a/src/click/shell_completion.py +++ b/src/click/shell_completion.py @@ -448,17 +448,16 @@ def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: ) -def _start_of_option(value: str) -> bool: +def _start_of_option(ctx: Context, value: str) -> bool: """Check if the value looks like the start of an option.""" if not value: return False c = value[0] - # Allow "/" since that starts a path. - return not c.isalnum() and c != "/" + return c in ctx._opt_prefixes -def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool: +def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool: """Determine if the given parameter is an option that needs a value. :param args: List of complete args before the incomplete value. @@ -467,7 +466,7 @@ def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool: if not isinstance(param, Option): return False - if param.is_flag: + if param.is_flag or param.count: return False last_option = None @@ -476,7 +475,7 @@ def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool: if index + 1 > param.nargs: break - if _start_of_option(arg): + if _start_of_option(ctx, arg): last_option = arg return last_option is not None and last_option in param.opts @@ -551,7 +550,7 @@ def _resolve_incomplete( # split and discard the "=" to make completion easier. if incomplete == "=": incomplete = "" - elif "=" in incomplete and _start_of_option(incomplete): + elif "=" in incomplete and _start_of_option(ctx, incomplete): name, _, incomplete = incomplete.partition("=") args.append(name) @@ -559,7 +558,7 @@ def _resolve_incomplete( # even if they start with the option character. If it hasn't been # given and the incomplete arg looks like an option, the current # command will provide option name completions. - if "--" not in args and _start_of_option(incomplete): + if "--" not in args and _start_of_option(ctx, incomplete): return ctx.command, incomplete params = ctx.command.get_params(ctx) @@ -567,7 +566,7 @@ def _resolve_incomplete( # If the last complete arg is an option name with an incomplete # value, the option will provide value completions. for param in params: - if _is_incomplete_option(args, param): + if _is_incomplete_option(ctx, args, param): return param, incomplete # It's not an option name or value. The first argument without a |