Skip to content

Instantly share code, notes, and snippets.

@GnikDroy
Created February 7, 2023 10:22
Show Gist options
  • Save GnikDroy/e6d74bef43871935df08cf6de979e680 to your computer and use it in GitHub Desktop.
Save GnikDroy/e6d74bef43871935df08cf6de979e680 to your computer and use it in GitHub Desktop.
See python-cmd2#1251
import sys
import zlib
from utils import COLOR_SCHEME as CS
from cmd2 import Cmd2ArgumentParser, set_default_argument_parser_type
import rich
def _(string, *args, **kwargs):
return rich.style.Style(*args, **kwargs).render(string)
def hsl_to_rgb(h, s, l):
c = (1 - abs(2 * l - 1)) * s
x = c * (1 - abs((h / 60) % 2 - 1))
m = l - c / 2
if h < 60:
r, g, b = c + m, x + m, 0 + m
elif h < 120:
r, g, b = x + m, c + m, 0 + m
elif h < 180:
r, g, b = 0 + m, c + m, x + m
elif h < 240:
r, g, b = 0 + m, x + m, c + m
elif h < 300:
r, g, b = x + m, 0 + m, c + m
else:
r, g, b = c + m, 0 + m, x + m
return (int(r * 255), int(g * 255), int(b * 255))
class ColoredArgParser(Cmd2ArgumentParser):
def _format_args(self, args, randomize_arg_color=True):
for arg in args:
arg.dest = _(arg.dest, color=CS['info'])
if randomize_arg_color:
h, s, l = zlib.adler32(arg.dest.encode()) % 360, 0.9, 0.7
color = rich.color.Color.from_rgb(*hsl_to_rgb(h, s, l))
arg.help = _(arg.help, color=color)
arg.option_strings = list(map(lambda x: _(x, color=color), arg.option_strings))
else:
arg.help = _(arg.help, color=CS['list'])
arg.option_strings = list(map(lambda x: _(x, color=CS['info']), arg.option_strings))
def format_help(self) -> str:
"""Copy of format_help() from argparse.ArgumentParser with tweaks to separately display required parameters"""
formatter = self._get_formatter()
# usage
formatter.add_usage(_(self.usage, color=CS["list"]), self._actions,
self._mutually_exclusive_groups,
_("Usage: ", color=CS["warn"])) # type: ignore[arg-type]
# description
formatter.add_text(_(self.description, color=CS["success"]))
# Begin cmd2 customization (separate required and optional arguments)
# positionals, optionals and user-defined groups
for action_group in self._action_groups:
if sys.version_info >= (3, 10):
default_options_group = action_group.title == 'options'
else:
default_options_group = action_group.title == 'optional arguments'
if default_options_group:
# check if the arguments are required, group accordingly
req_args = []
opt_args = []
for action in action_group._group_actions:
if action.required:
req_args.append(action)
else:
opt_args.append(action)
# separately display required arguments
formatter.start_section(_('required arguments', color=CS['warn']))
formatter.add_text(action_group.description)
self._format_args(req_args)
formatter.add_arguments(req_args)
formatter.end_section()
# now display truly optional arguments
formatter.start_section(_('optional arguments', color=CS['warn']))
formatter.add_text(action_group.description)
self._format_args(opt_args)
formatter.add_arguments(opt_args)
formatter.end_section()
else:
formatter.start_section(_(action_group.title, color=CS['warn']))
formatter.add_text(action_group.description)
self._format_args(action_group._group_actions)
formatter.add_arguments(action_group._group_actions)
formatter.end_section()
# End cmd2 customization
# epilog
formatter.add_text(_(self.epilog, color=CS['warn']))
# determine help from format above
return formatter.format_help()
set_default_argument_parser_type(ColoredArgParser)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment