Skip to content

feat: add align_panel_columns to align Rich help panel columns - #1935

Open
spacemonkeyrocks wants to merge 5 commits into
fastapi:masterfrom
spacemonkeyrocks:pr-align-panel-columns
Open

feat: add align_panel_columns to align Rich help panel columns#1935
spacemonkeyrocks wants to merge 5 commits into
fastapi:masterfrom
spacemonkeyrocks:pr-align-panel-columns

Conversation

@spacemonkeyrocks

Copy link
Copy Markdown

Summary

Add an opt-in align_panel_columns: bool = False option to typer.Typer.

When disabled (the default), behaviour is unchanged: each Rich --help
options panel sizes its own columns independently. When enabled, every panel
is rendered with a shared set of fixed column widths computed from all
options in the command, so the option columns line up across panels.

Motivation

Typer renders each options panel as its own Rich Table with no fixed
column widths, so columns drift out of alignment between panels. For a
command with several rich_help_panel groups the result is ragged. The two
examples below are the real --help output of a CLI with five option panels,
at 70 columns.

Off (align_panel_columns=False):

╭─ Options ──────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                      │
╰────────────────────────────────────────────────────────────────────╯
╭─ Selection options ────────────────────────────────────────────────╮
│ --config  -c      <path>  YAML config file                         │
│ --pairs   -p      <str>   Comma-separated pairs (overrides config) │
│ --years   -Y      <str>   Year range, e.g. 2017-, 2017-2025,       │
│                           2017,2020 (overrides config)             │
╰────────────────────────────────────────────────────────────────────╯
╭─ Output options ───────────────────────────────────────────────────╮
│ --human         -H             Print a table instead of JSON       │
│ --decimal       -D      <int>  Close-price decimals in --human     │
│                                mode                                │
│ --pretty-print  -P             Pretty-print the JSON output        │
╰────────────────────────────────────────────────────────────────────╯
╭─ Logging options ──────────────────────────────────────────────────╮
│              -v      <int>  Verbosity: -v info, -vv debug, -vvv    │
│ --log-path           <str>  Log file or directory (overrides       │
│ --log-level          <str>  Log level: trace, debug, info,         │
╰────────────────────────────────────────────────────────────────────╯

On (align_panel_columns=True):

╭─ Options ──────────────────────────────────────────────────────────╮
│ --help          -h              Show this message and exit.        │
╰────────────────────────────────────────────────────────────────────╯
╭─ Selection options ────────────────────────────────────────────────╮
│ --config        -c      <path>  YAML config file                   │
│ --pairs         -p      <str>   Comma-separated pairs (overrides   │
│ --years         -Y      <str>   Year range, e.g. 2017-, 2017-2025, │
╰────────────────────────────────────────────────────────────────────╯
╭─ Output options ───────────────────────────────────────────────────╮
│ --human         -H              Print a table instead of JSON      │
│ --decimal       -D      <int>   Close-price decimals in --human    │
│ --pretty-print  -P              Pretty-print the JSON output       │
╰────────────────────────────────────────────────────────────────────╯
╭─ Logging options ──────────────────────────────────────────────────╮
│                 -v      <int>   Verbosity: -v info, -vv debug,     │
│ --log-path              <str>   Log file or directory (overrides   │
│ --log-level             <str>   Log level: trace, debug, info,     │
╰────────────────────────────────────────────────────────────────────╯

Notice how -c, -p, -Y, -f, -H, -P and -v all start at the same
column, and the <path>/<str>/<int> metavar column lines up, once the
flag is enabled.

Implementation

The existing option-row building is reused unchanged; only the table column
setup branches on the flag. When enabled, a shared set of fixed column widths
is derived from every visible option in the command and the same widths are
applied to each panel. No renderer code is duplicated and no existing
behaviour changes unless the option is turned on.

Tests

Added test_align_panel_columns_true_aligns_columns and
test_align_panel_columns_false_is_default_unaligned to
tests/test_rich_utils.py.

spacemonkeyrocks and others added 5 commits August 20, 2026 15:00
Add align_option_panels to typer.Typer. When enabled, every Rich help
panel is rendered with a shared set of fixed column widths computed from
all options in the command, so option columns line up across panels. It
defaults to False, preserving existing behaviour.

The option-panel row building is reused unchanged; only the table column
setup branches on the flag.
Rename align_option_panels to align_panel_columns for clarity (it aligns
columns across panels). Public API name changes on the Typer flag; behaviour
and tests unchanged.
Windows CI renders Rich panels with ASCII borders (|, +) instead of rounded
Unicode (│, ╭). Detect option rows by stripping any leading border char +
spaces rather than matching a specific box style, so the new alignment tests
pass on Windows too.
Add a ranged option (min/max) and a required-option variant to the
align_panel_columns test app so every new code path is covered, keeping the
fork at 100% coverage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants