Skip to content
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/tutorial/commands/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,26 @@ $ python main.py --help

You can see the custom panel for the commands for "`Utils and Configs`".

## Expand or Fit

By default, the help panels all expand to match the width of your terminal window.

For a CLI with few parameters, especially on wide terminal windows, you might prefer a more narrow layout.
You can do this by initializing your Typer with `rich_expand=False`, like this:

```python
app = typer.Typer(rich_expand=False)
```

Or if you use `typer.run()`, for simple apps:

```python
typer.run(main, rich_expand=False)
```

Your help panels will all fit to their contents, which also means they will probably have different widths.
It's a different look, and sometimes you might prefer it as an option.

## Epilog

If you need, you can also add an epilog section to the help of your commands:
Expand Down
11 changes: 10 additions & 1 deletion typer/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def _main(
standalone_mode: bool = True,
windows_expand_args: bool = True,
rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
rich_expand: bool = True,
**extra: Any,
) -> Any:
# Typer override, duplicated from click.main() to handle custom rich exceptions
Expand Down Expand Up @@ -212,7 +213,7 @@ def _main(
if HAS_RICH and rich_markup_mode is not None:
from . import rich_utils

rich_utils.rich_format_error(e)
rich_utils.rich_format_error(e, expand=rich_expand)
else:
e.show()
# Typer override end
Expand Down Expand Up @@ -674,6 +675,7 @@ def __init__(
# Rich settings
rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
rich_help_panel: Union[str, None] = None,
rich_expand: bool = True,
) -> None:
super().__init__(
name=name,
Expand All @@ -691,6 +693,7 @@ def __init__(
)
self.rich_markup_mode: MarkupMode = rich_markup_mode
self.rich_help_panel = rich_help_panel
self.rich_expand = rich_expand

def format_options(
self, ctx: click.Context, formatter: click.HelpFormatter
Expand Down Expand Up @@ -724,6 +727,7 @@ def main(
standalone_mode=standalone_mode,
windows_expand_args=windows_expand_args,
rich_markup_mode=self.rich_markup_mode,
rich_expand=self.rich_expand,
**extra,
)

Expand All @@ -736,6 +740,7 @@ def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> Non
obj=self,
ctx=ctx,
markup_mode=self.rich_markup_mode,
expand=self.rich_expand,
)


Expand All @@ -750,12 +755,14 @@ def __init__(
# Rich settings
rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
rich_help_panel: Union[str, None] = None,
rich_expand: bool = True,
suggest_commands: bool = True,
**attrs: Any,
) -> None:
super().__init__(name=name, commands=commands, **attrs)
self.rich_markup_mode: MarkupMode = rich_markup_mode
self.rich_help_panel = rich_help_panel
self.rich_expand = rich_expand
self.suggest_commands = suggest_commands

def format_options(
Expand Down Expand Up @@ -808,6 +815,7 @@ def main(
standalone_mode=standalone_mode,
windows_expand_args=windows_expand_args,
rich_markup_mode=self.rich_markup_mode,
rich_expand=self.rich_expand,
**extra,
)

Expand All @@ -820,6 +828,7 @@ def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> Non
obj=self,
ctx=ctx,
markup_mode=self.rich_markup_mode,
expand=self.rich_expand,
)

def list_commands(self, ctx: click.Context) -> List[str]:
Expand Down
14 changes: 12 additions & 2 deletions typer/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ def __init__(
add_completion: bool = True,
# Rich settings
rich_markup_mode: MarkupMode = Default(DEFAULT_MARKUP_MODE),
rich_expand: bool = True,
rich_help_panel: Union[str, None] = Default(None),
suggest_commands: bool = True,
pretty_exceptions_enable: bool = True,
Expand All @@ -142,6 +143,7 @@ def __init__(
):
self._add_completion = add_completion
self.rich_markup_mode: MarkupMode = rich_markup_mode
self.rich_expand = rich_expand
self.rich_help_panel = rich_help_panel
self.suggest_commands = suggest_commands
self.pretty_exceptions_enable = pretty_exceptions_enable
Expand Down Expand Up @@ -332,6 +334,7 @@ def get_group(typer_instance: Typer) -> TyperGroup:
TyperInfo(typer_instance),
pretty_exceptions_short=typer_instance.pretty_exceptions_short,
rich_markup_mode=typer_instance.rich_markup_mode,
rich_expand=typer_instance.rich_expand,
suggest_commands=typer_instance.suggest_commands,
)
return group
Expand Down Expand Up @@ -365,6 +368,7 @@ def get_command(typer_instance: Typer) -> click.Command:
single_command,
pretty_exceptions_short=typer_instance.pretty_exceptions_short,
rich_markup_mode=typer_instance.rich_markup_mode,
rich_expand=typer_instance.rich_expand,
)
if typer_instance._add_completion:
click_command.params.append(click_install_param)
Expand Down Expand Up @@ -461,6 +465,7 @@ def get_group_from_info(
pretty_exceptions_short: bool,
suggest_commands: bool,
rich_markup_mode: MarkupMode,
rich_expand: bool,
) -> TyperGroup:
assert group_info.typer_instance, (
"A Typer instance is needed to generate a Click Group"
Expand All @@ -471,6 +476,7 @@ def get_group_from_info(
command_info=command_info,
pretty_exceptions_short=pretty_exceptions_short,
rich_markup_mode=rich_markup_mode,
rich_expand=rich_expand,
)
if command.name:
commands[command.name] = command
Expand All @@ -479,6 +485,7 @@ def get_group_from_info(
sub_group_info,
pretty_exceptions_short=pretty_exceptions_short,
rich_markup_mode=rich_markup_mode,
rich_expand=rich_expand,
suggest_commands=suggest_commands,
)
if sub_group.name:
Expand Down Expand Up @@ -526,6 +533,7 @@ def get_group_from_info(
hidden=solved_info.hidden,
deprecated=solved_info.deprecated,
rich_markup_mode=rich_markup_mode,
rich_expand=rich_expand,
# Rich settings
rich_help_panel=solved_info.rich_help_panel,
suggest_commands=suggest_commands,
Expand Down Expand Up @@ -561,6 +569,7 @@ def get_command_from_info(
*,
pretty_exceptions_short: bool,
rich_markup_mode: MarkupMode,
rich_expand: bool,
) -> click.Command:
assert command_info.callback, "A command must have a callback function"
name = command_info.name or get_command_name(command_info.callback.__name__)
Expand Down Expand Up @@ -595,6 +604,7 @@ def get_command_from_info(
hidden=command_info.hidden,
deprecated=command_info.deprecated,
rich_markup_mode=rich_markup_mode,
rich_expand=rich_expand,
# Rich settings
rich_help_panel=command_info.rich_help_panel,
)
Expand Down Expand Up @@ -1071,8 +1081,8 @@ def wrapper(ctx: click.Context, args: List[str], incomplete: Optional[str]) -> A
return wrapper


def run(function: Callable[..., Any]) -> None:
app = Typer(add_completion=False)
def run(function: Callable[..., Any], rich_expand: bool = True) -> None:
app = Typer(add_completion=False, rich_expand=rich_expand)
app.command()(function)
app()

Expand Down
33 changes: 27 additions & 6 deletions typer/rich_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ def _get_parameter_help(
param: Union[click.Option, click.Argument, click.Parameter],
ctx: click.Context,
markup_mode: MarkupMode,
) -> Columns:
rich_expand: bool = True,
) -> Union[Table, Column]:
"""Build primary help text for a click option or argument.

Returns the prose help text for an option or argument, rendered either
Expand Down Expand Up @@ -313,9 +314,16 @@ def _get_parameter_help(
if param.required:
items.append(Text(REQUIRED_LONG_STRING, style=STYLE_REQUIRED_LONG))

# Use Columns - this allows us to group different renderable types
# (Text, Markdown) onto a single line.
return Columns(items)
if rich_expand:
# Use Columns - this allows us to group different renderable types
# (Text, Markdown) onto a single line.
return Columns(items)

# Use Table - this allows us to group different renderable types
# (Text, Markdown) onto a single line without using the full screen width.
help_table = Table.grid(padding=(0, 1), expand=False)
help_table.add_row(*items)
return help_table


def _make_command_help(
Expand Down Expand Up @@ -351,6 +359,7 @@ def _print_options_panel(
params: Union[List[click.Option], List[click.Argument]],
ctx: click.Context,
markup_mode: MarkupMode,
expand: bool,
console: Console,
) -> None:
options_rows: List[List[RenderableType]] = []
Expand Down Expand Up @@ -433,6 +442,7 @@ class MetavarHighlighter(RegexHighlighter):
param=param,
ctx=ctx,
markup_mode=markup_mode,
rich_expand=expand,
),
]
)
Expand All @@ -457,7 +467,7 @@ class MetavarHighlighter(RegexHighlighter):
options_table = Table(
highlight=True,
show_header=False,
expand=True,
expand=False,
box=box_style,
**t_styles,
)
Expand All @@ -468,6 +478,7 @@ class MetavarHighlighter(RegexHighlighter):
options_table,
border_style=STYLE_OPTIONS_PANEL_BORDER,
title=name,
expand=expand,
title_align=ALIGN_OPTIONS_PANEL,
)
)
Expand All @@ -478,6 +489,7 @@ def _print_commands_panel(
name: str,
commands: List[click.Command],
markup_mode: MarkupMode,
expand: bool,
console: Console,
cmd_len: int,
) -> None:
Expand Down Expand Up @@ -544,6 +556,7 @@ def _print_commands_panel(
commands_table,
border_style=STYLE_COMMANDS_PANEL_BORDER,
title=name,
expand=expand,
title_align=ALIGN_COMMANDS_PANEL,
)
)
Expand All @@ -554,6 +567,7 @@ def rich_format_help(
obj: Union[click.Command, click.Group],
ctx: click.Context,
markup_mode: MarkupMode,
expand: bool,
) -> None:
"""Print nicely formatted help text using rich.

Expand Down Expand Up @@ -607,6 +621,7 @@ def rich_format_help(
params=default_arguments,
ctx=ctx,
markup_mode=markup_mode,
expand=expand,
console=console,
)
for panel_name, arguments in panel_to_arguments.items():
Expand All @@ -618,6 +633,7 @@ def rich_format_help(
params=arguments,
ctx=ctx,
markup_mode=markup_mode,
expand=expand,
console=console,
)
default_options = panel_to_options.get(OPTIONS_PANEL_TITLE, [])
Expand All @@ -626,6 +642,7 @@ def rich_format_help(
params=default_options,
ctx=ctx,
markup_mode=markup_mode,
expand=expand,
console=console,
)
for panel_name, options in panel_to_options.items():
Expand All @@ -637,6 +654,7 @@ def rich_format_help(
params=options,
ctx=ctx,
markup_mode=markup_mode,
expand=expand,
console=console,
)

Expand Down Expand Up @@ -667,6 +685,7 @@ def rich_format_help(
name=COMMANDS_PANEL_TITLE,
commands=default_commands,
markup_mode=markup_mode,
expand=expand,
console=console,
cmd_len=max_cmd_len,
)
Expand All @@ -678,6 +697,7 @@ def rich_format_help(
name=panel_name,
commands=commands,
markup_mode=markup_mode,
expand=expand,
console=console,
cmd_len=max_cmd_len,
)
Expand All @@ -691,7 +711,7 @@ def rich_format_help(
console.print(Padding(Align(epilogue_text, pad=False), 1))


def rich_format_error(self: click.ClickException) -> None:
def rich_format_error(self: click.ClickException, expand: bool = True) -> None:
"""Print richly formatted click errors.

Called by custom exception handler to print richly formatted click errors.
Expand All @@ -718,6 +738,7 @@ def rich_format_error(self: click.ClickException) -> None:
Panel(
highlighter(self.format_message()),
border_style=STYLE_ERRORS_PANEL_BORDER,
expand=expand,
title=ERRORS_PANEL_TITLE,
title_align=ALIGN_ERRORS_PANEL,
)
Expand Down
Loading