Skip to content

Instantly share code, notes, and snippets.

@sp1ff
Last active January 7, 2018 03:09
Show Gist options
  • Save sp1ff/f315e7074e0a03eeb1a6ee0d25b71aba to your computer and use it in GitHub Desktop.
Save sp1ff/f315e7074e0a03eeb1a6ee0d25b71aba to your computer and use it in GitHub Desktop.
Customize click help
""""Click, by default, will re-purpose docstrings for help messages. I don't
care for this choice: docstrings are generally authored in ReStructredText
(cf. PEP-287), but the default click implementation does no rendering for the
terminal. Furthermore, if you don't want click to wrap lines for a given
paragraph (a code snippet, e.g.) you need to add click-specific markup
for it. Finally, it doesn't offer any support for paged help (like git e.g.)
The click .. _docs:http://click.pocoo.org/6/documentation/#help-texts state
that help pages "...are currently not customizable in terms of their
layout...", but that's not true.
"""
import click
def _help(ctx, value, header, synopsis, discussion, paged=True):
"""Print a nicely formatted help message.
:param ctx click.Context: The current click Context instance
:param header str: Heading for this help page
:param synopsis str: A brief description of this command
:param discussion str: A discussion of this command of arbitrary length
Print a help page in a nicer format using ANSI escape codes.
"""
from click.formatting import HelpFormatter
from click.termui import echo, echo_via_pager
if not value or ctx.resilient_parsing:
return
fmt = HelpFormatter()
fmt.write_text('' + header + '')
fmt.write_paragraph()
pieces = ctx.command.collect_usage_pieces(ctx)
fmt.write_usage(ctx.command_path, ' '.join(pieces), 'Usage\n\n')
fmt.write_paragraph()
with fmt.indentation():
fmt.write_text(synopsis)
ctx.command.format_options(ctx, fmt)
fmt.write_paragraph()
if discussion:
fmt.write_text('Discussion')
fmt.write_paragraph()
with fmt.indentation():
fmt.write_text(discussion)
if paged:
echo_via_pager(fmt.getvalue(), ctx.color)
else:
echo(fmt.getvalue(), ctx.color)
ctx.exit()
def help(**attrs):
"""A decorator for adding a customized help message.
:param header str: The header to be printed on this help page
:param synopsis str: A brief description of your command
:param discussion str: A lengthier description of your command
:param paged bool: Optional, if True, pipe the help page through a pager
"""
from click.decorators import _param_memo
header = attrs.pop('header')
synopsis = attrs.pop('synopsis')
discussion = attrs.pop('discussion')
paged = attrs.pop('paged', False)
def _shim(ctx, param, value):
_help(ctx, value, header, synopsis, discussion, paged)
def decorator(f):
_param_memo(f, click.Option(['-h', '--help'],
help='Print this message & exit with status zero',
is_flag=True, is_eager=True, expose_value=False,
callback=_shim))
return f
return decorator
header = 'my command'
synopsis = 'This is a trivial click command.'
discussion = 'This is a longer discussion'
@click.command(add_help_option=False)
@help(header=header, synopsis=synopsis, discussion=discussion)
def cli():
pass
if __name__ == '__main__':
cli()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment