3

I'm trying to allow users to edit a parameter from a config file using Click. What I would like to do is present them with the previous parameter prefilled in a prompt input so that they can edit it directly, rather than making them type it all out again. For example, if the parameter is 'test.com', I'd like my prompt to present something like this:

Edit Domain Name: testdomain.com

With the testdomain.com being editable. Then when they add a 1 so it reads testdomain1.com, the prompt returns testdomain1.com back to the code. There are a couple other posts from 10 years ago with readline and other more vanilla-python-like options like here and here, but nothing that I can figure out from the Click documentation.

Anyone have any ideas? Thanks!

ConorBaumgart
  • 493
  • 1
  • 3
  • 18
  • I don't think this question is really about Click, you're basically asking "how can I use `input()` or something like it, while prefilling the response?" - the answer to that is to use `readline` on Linux, or a third party library like `pyreadline` on Windows for the same effect. It's like using `input()`, but allows you to pass a value to prefill - the user can leave it or edit it and whatever they do, the result is returned. – Grismar Oct 08 '21 at 22:09
  • You can have default, that can be accepted by `enter` but I don't think prefill in terms of actual editable default is possible. Are you aware of the default behaviour? – Cornelius Roemer Oct 08 '21 at 23:23

1 Answers1

1

Prompts are not the most user-friendly for editing text.
Fortunately, there is a way around this.

Take, for example, git commit.
If you don't specify the --message or -m option, git commit opens up an editor for the user to type a commit message in.

You might want to consider prompting your users with a text-editor too.
You can achieve this with python-click as follows:

import click

def promp_user_with_editor(old_param: str) -> str:
    comment = "# Edit Domain Name:\n"
    editor_content = f"{comment}{old_param}"
    result = click.edit(editor_content)
    # In real code, you would properly handle the user's input here.
    new_param = result.split(comment)[1].strip()
    return new_param

@click.command()
def main():
    new_param = promp_user_with_editor(old_param="testdomain.com")
    click.echo(f"{new_param=}")

if __name__ == "__main__":
    main()

Now running this code as:

python3 the_name_of_the_above_file.py

Will prompt me with:

# Edit Domain Name:
testdomain.com

If I change that to:

# Edit Domain Name:
stackoverflow.com

The output is:

new_param='stackoverflow.com'
melvio
  • 762
  • 6
  • 24
  • 1
    Thanks for your response and sorry for the delay - this got pushed back a couple weeks at work. This is what I ended up going with, thank you! – ConorBaumgart Nov 04 '21 at 16:29