Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
.. currentmodule:: click

Version 7.2
-----------

- Include ``--help`` option in completion. :pr:`1504`


Version 7.1.2
-------------

Expand Down
6 changes: 3 additions & 3 deletions src/click/_bashcomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ def get_choices(cli, prog_name, args, incomplete):
completions = []
if not has_double_dash and start_of_option(incomplete):
# completions for partial options
for param in ctx.command.params:
for param in ctx.command.get_params(ctx):
if isinstance(param, Option) and not param.hidden:
param_opts = [
param_opt
Expand All @@ -309,11 +309,11 @@ def get_choices(cli, prog_name, args, incomplete):
)
return completions
# completion for option values from user supplied values
for param in ctx.command.params:
for param in ctx.command.get_params(ctx):
if is_incomplete_option(all_args, param):
return get_user_autocompletions(ctx, all_args, incomplete, param)
# completion for argument values from user supplied values
for param in ctx.command.params:
for param in ctx.command.get_params(ctx):
if is_incomplete_argument(ctx.params, param):
return get_user_autocompletions(ctx, all_args, incomplete, param)

Expand Down
62 changes: 41 additions & 21 deletions tests/test_bashcomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def test_single_command():
def cli(local_opt):
pass

assert choices_without_help(cli, [], "-") == ["--local-opt"]
assert choices_without_help(cli, [], "-") == ["--local-opt", "--help"]
assert choices_without_help(cli, [], "") == []


Expand All @@ -30,7 +30,7 @@ def test_boolean_flag():
def cli(local_opt):
pass

assert choices_without_help(cli, [], "-") == ["--shout", "--no-shout"]
assert choices_without_help(cli, [], "-") == ["--shout", "--no-shout", "--help"]


def test_multi_value_option():
Expand All @@ -44,7 +44,7 @@ def cli(local_opt):
def sub(local_opt):
pass

assert choices_without_help(cli, [], "-") == ["--pos"]
assert choices_without_help(cli, [], "-") == ["--pos", "--help"]
assert choices_without_help(cli, ["--pos"], "") == []
assert choices_without_help(cli, ["--pos", "1.0"], "") == []
assert choices_without_help(cli, ["--pos", "1.0", "1.0"], "") == ["sub"]
Expand All @@ -56,7 +56,7 @@ def test_multi_option():
def cli(local_opt):
pass

assert choices_without_help(cli, [], "-") == ["--message", "-m"]
assert choices_without_help(cli, [], "-") == ["--message", "-m", "--help"]
assert choices_without_help(cli, ["-m"], "") == []


Expand All @@ -72,9 +72,9 @@ def sub(local_opt):
pass

assert choices_without_help(cli, [], "") == ["sub"]
assert choices_without_help(cli, [], "-") == ["--global-opt"]
assert choices_without_help(cli, [], "-") == ["--global-opt", "--help"]
assert choices_without_help(cli, ["sub"], "") == []
assert choices_without_help(cli, ["sub"], "-") == ["--local-opt"]
assert choices_without_help(cli, ["sub"], "-") == ["--local-opt", "--help"]


def test_long_chain():
Expand Down Expand Up @@ -116,16 +116,17 @@ def search_colors(ctx, args, incomplete):
def csub(csub_opt, color):
pass

assert choices_without_help(cli, [], "-") == ["--cli-opt"]
assert choices_without_help(cli, [], "-") == ["--cli-opt", "--help"]
assert choices_without_help(cli, [], "") == ["asub"]
assert choices_without_help(cli, ["asub"], "-") == ["--asub-opt"]
assert choices_without_help(cli, ["asub"], "-") == ["--asub-opt", "--help"]
assert choices_without_help(cli, ["asub"], "") == ["bsub"]
assert choices_without_help(cli, ["asub", "bsub"], "-") == ["--bsub-opt"]
assert choices_without_help(cli, ["asub", "bsub"], "-") == ["--bsub-opt", "--help"]
assert choices_without_help(cli, ["asub", "bsub"], "") == ["csub"]
assert choices_without_help(cli, ["asub", "bsub", "csub"], "-") == [
"--csub-opt",
"--csub",
"--search-color",
"--help",
]
assert (
choices_without_help(cli, ["asub", "bsub", "csub", "--csub-opt"], "")
Expand Down Expand Up @@ -173,16 +174,22 @@ def bsub(bsub_opt, arg):
def csub(csub_opt, arg):
pass

assert choices_without_help(cli, [], "-") == ["--cli-opt"]
assert choices_without_help(cli, [], "-") == ["--cli-opt", "--help"]
assert choices_without_help(cli, [], "") == ["cliarg1", "cliarg2"]
assert choices_without_help(cli, ["cliarg1", "asub"], "-") == ["--asub-opt"]
assert choices_without_help(cli, ["cliarg1", "asub"], "-") == [
"--asub-opt",
"--help",
]
assert choices_without_help(cli, ["cliarg1", "asub"], "") == ["bsub", "csub"]
assert choices_without_help(cli, ["cliarg1", "bsub"], "") == ["arg1", "arg2"]
assert choices_without_help(cli, ["cliarg1", "asub", "--asub-opt"], "") == []
assert choices_without_help(
cli, ["cliarg1", "asub", "--asub-opt", "5", "bsub"], "-"
) == ["--bsub-opt"]
assert choices_without_help(cli, ["cliarg1", "asub", "bsub"], "-") == ["--bsub-opt"]
) == ["--bsub-opt", "--help"]
assert choices_without_help(cli, ["cliarg1", "asub", "bsub"], "-") == [
"--bsub-opt",
"--help",
]
assert choices_without_help(cli, ["cliarg1", "asub", "csub"], "") == [
"carg1",
"carg2",
Expand All @@ -191,7 +198,10 @@ def csub(csub_opt, arg):
"carg1",
"carg2",
]
assert choices_without_help(cli, ["cliarg1", "asub", "csub"], "-") == ["--csub-opt"]
assert choices_without_help(cli, ["cliarg1", "asub", "csub"], "-") == [
"--csub-opt",
"--help",
]
assert choices_with_help(cli, ["cliarg1", "asub"], "b") == [("bsub", "bsub help")]


Expand Down Expand Up @@ -222,6 +232,7 @@ def cli():
("--opt1", "opt1 help"),
("--opt2", None),
("--opt3", None),
("--help", "Show this message and exit."),
]
assert choices_without_help(cli, [], "--opt") == ["--opt1", "--opt2", "--opt3"]
assert choices_without_help(cli, [], "--opt1=") == ["opt11", "opt12"]
Expand All @@ -234,14 +245,23 @@ def cli():
"opt21",
"opt22",
]
assert choices_without_help(cli, ["--opt2", "opt21"], "-") == ["--opt1", "--opt3"]
assert choices_without_help(cli, ["--opt1", "opt11"], "-") == ["--opt2", "--opt3"]
assert choices_without_help(cli, ["--opt2", "opt21"], "-") == [
"--opt1",
"--opt3",
"--help",
]
assert choices_without_help(cli, ["--opt1", "opt11"], "-") == [
"--opt2",
"--opt3",
"--help",
]
assert choices_without_help(cli, ["--opt1"], "opt") == ["opt11", "opt12"]
assert choices_without_help(cli, ["--opt3"], "opti") == ["option"]

assert choices_without_help(cli, ["--opt1", "invalid_opt"], "-") == [
"--opt2",
"--opt3",
"--help",
]


Expand All @@ -268,7 +288,7 @@ def test_boolean_flag_choice():
def cli(local_opt):
pass

assert choices_without_help(cli, [], "-") == ["--shout", "--no-shout"]
assert choices_without_help(cli, [], "-") == ["--shout", "--no-shout", "--help"]
assert choices_without_help(cli, ["--shout"], "") == ["arg1", "arg2"]


Expand Down Expand Up @@ -382,7 +402,7 @@ def dsub():
]
assert choices_without_help(
cli, ["sub", "--sub-opt", "subopt1", "subarg1", "bsub"], "-"
) == ["--bsub-opt"]
) == ["--bsub-opt", "--help"]
assert choices_without_help(
cli, ["sub", "--sub-opt", "subopt1", "subarg1", "bsub"], ""
) == ["bsubarg1", "bsubarg2"]
Expand Down Expand Up @@ -472,14 +492,14 @@ def hsub():
assert choices_without_help(cli, [], "h") == []
# If the user exactly types out the hidden command, complete its subcommands.
assert choices_without_help(cli, ["hgroup"], "") == ["hgroupsub"]
assert choices_without_help(cli, ["hsub"], "--h") == ["--hname"]
assert choices_without_help(cli, ["hsub"], "--h") == ["--hname", "--help"]


@pytest.mark.parametrize(
("args", "part", "expect"),
[
([], "-", ["--opt"]),
(["value"], "--", ["--opt"]),
([], "-", ["--opt", "--help"]),
(["value"], "--", ["--opt", "--help"]),
([], "-o", []),
(["--opt"], "-o", []),
(["--"], "", ["name", "-o", "--opt", "--"]),
Expand Down