click-contrib / click-repl

Subcommand REPL for click apps
MIT License
219 stars 40 forks source link

Flags are treated as regular boolean values #116

Open ChristopherHammond13 opened 7 months ago

ChristopherHammond13 commented 7 months ago

I have started the process of exploring whether we can move one of our Cmd2 tools over to click-repl to benefit from the Prompt Toolkit backend, but seem to have hit an edge case with Click flags.

Minimal reproduction:

import click

from click_repl import repl
from prompt_toolkit.shortcuts import CompleteStyle

@click.group
def my_cli():
    pass

@my_cli.command(name="test")
@click.argument("arg1", type=click.STRING)
@click.option(
    "-b",
    "--some-option",
    "some_option",
    help="Toggle on a flag",
    is_flag=True,
    show_default=False,
    default=False,
)
def my_command(arg1, some_option):
    print(f"{arg1} // {some_option}")

@my_cli.command
def myrepl():
    prompt_kwargs = {
        "complete_style": CompleteStyle.COLUMN,
        "validate_while_typing": False,
    }
    repl(click.get_current_context(), prompt_kwargs=prompt_kwargs)

my_cli(["myrepl"])

This results in the following UI being shown to the user, which erroneously suggests that a value must be provided for the boolean flag. However, as this click argument definition should result in a flag that somewhat mirrors the argparse store_true option, this is wrong:

image

Furthermore, if one of the options shown (true/false) is chosen, it takes the place of the positional argument arg1 resulting in the following error:

image

Expected result: when show_flag=True, click-repl should not suggest a parameter for the option as it's a flag. Instead, the user should be prompted to just type the value of the positional argument to get a response, like this:

image

I suspect the issue lies somewhere in this function, but I don't know enough about Prompt Toolkit completers to fix this myself in the case that is_flag is True.

Thank you in advance!