hamdanal / rich-argparse

A rich help formatter for argparse
https://pypi.org/project/rich-argparse/
MIT License
129 stars 11 forks source link

Implement `argparse.prog` style #55

Closed kotfu closed 1 year ago

kotfu commented 1 year ago

Add a new style to highlight the name of the program. This might look like

RichHelpFormatter.styles["argparse.prog"] = "deep_sky_blue1"

This style would be applied to the prog parameter of the argparse.ArgumentParser() constructor. In the example below, the prog is connect:

prsr = argparse.ArgumentParser(
    prog="connect",
    description="Edit or show the location of the user configuration file.",
    usage="%(prog)s [-h] config_name\n       %(prog)s [-h] url [user] [password]",
    formatter_class=rich_argparse.RichHelpFormatter,
)

This formatting should be applied whether the usage parameter is given, as it is in the example above, or if the usage parameter is absent.

hamdanal commented 1 year ago

This is not as simple as it looks as argparse calls formatter.format_help() internally to get the prog parameter when creating subparsers. Adding styles to prog may mess up the subparsers use case. I'll look into it more to see if a solution can be implemented that doesn't break subparsers.

hamdanal commented 1 year ago

This is implemented in #56. @kotfu I appreciate it if you could take a look at that PR and tell me if it answers your request.

kotfu commented 1 year ago

This works exactly as I hoped. Thanks for implementing it. 🥳

kotfu commented 1 year ago

After further experimenting, I think I found a bug which was introduced by this PR. Consider the following:

import argparse
import rich.console
from rich_argparse import RichHelpFormatter

console = rich.console.Console(markup=False, emoji=False, highlight=False)
parser = argparse.ArgumentParser(
    prog="list",
    description="Show all installed applications",
    add_help=False,
    formatter_class=RichHelpFormatter,
)
parser.add_argument(
    "config_name",
    nargs="?",
    help="a configuration name",
)
parser.add_argument(
    "-r",
    "--raw",
    action="store_true",
    required=True,
    help="show apps without formatting",
)
parser.add_argument(
    "-s",
    "--state",
    choices=["running", "stopped"],
    help="only show apps in a given state",
)
console.print(parser.format_help())

In the released 1.0.0 version, the output is:

Usage: list -r [-s {running,stopped}] [config_name]

Show all installed applications

Positional Arguments:
  config_name           a configuration name

Options:
  -r, --raw             show apps without formatting
  -s, --state {running,stopped}
                        only show apps in a given state

In the unreleased main branch, the output is:

Usage: list -r [-s {running,stopped}]
[config_name]

Show all installed applications

Positional Arguments:
  config_name           a configuration name

Options:
  -r, --raw             show apps without formatting
  -s, --state {running,stopped}
                        only show apps in a given state
hamdanal commented 1 year ago

After further experimenting, I think I found a bug which was introduced by this PR

Thanks for the report. Could you please open a new issue for this? I'll take a look soon.