There is now a library called click_repl that does most of the work for you. Thought I'd share my efforts in getting this to work.
The one difficulty is that you have to make a specific command the repl
command, but we can repurpose @fpbhb's approach to allow calling that command by default if another one isn't provided.
This is a fully working example that supports all click options, with command history, as well as being able to call commands directly without entering the REPL:
import click
import click_repl
import os
from prompt_toolkit.history import FileHistory
@click.group(invoke_without_command=True)
@click.pass_context
def cli(ctx):
"""Pleasantries CLI"""
if ctx.invoked_subcommand is None:
ctx.invoke(repl)
@cli.command()
@click.option('--name', default='world')
def hello(name):
"""Say hello"""
click.echo('Hello, {}!'.format(name))
@cli.command()
@click.option('--name', default='moon')
def goodnight(name):
"""Say goodnight"""
click.echo('Goodnight, {}.'.format(name))
@cli.command()
def repl():
"""Start an interactive session"""
prompt_kwargs = {
'history': FileHistory(os.path.expanduser('~/.repl_history'))
}
click_repl.repl(click.get_current_context(), prompt_kwargs=prompt_kwargs)
if __name__ == '__main__':
cli(obj={})
Here's what it looks like to use the REPL:
$ python pleasantries.py
> hello
Hello, world!
> goodnight --name fpbhb
Goodnight, fpbhb.
And to use the command line subcommands directly:
$ python pleasntries.py goodnight
Goodnight, moon.
prompt
function. – Suntan