rich icon indicating copy to clipboard operation
rich copied to clipboard

[BUG] Right-justified panels with right-aligned titles display incorrectly

Open NorthIsUp opened this issue 10 months ago • 5 comments

  • [ ] I've checked docs and closed issues for possible solutions.
  • [x] I can't find my issue in the FAQ.

Describe the bug

a picture is worth a thousand words, the issue is the gap in the box

Image note: "a" is an extra gap and "b" the missing gap

In [4]: panel = Panel("hi", title="[red]ho", title_align="right", width=20, style="blue")

In [5]: Console().print(panel, justify='right')
                                                                      ╭─ ──────────── ho─╮
                                                                      │               hi │
                                                                      ╰──────────────────╯

In [6]: panel = Panel("hi", title="[red]ho", title_align="left", width=20, style="blue")

In [7]: Console().print(panel, justify='right')
                                                                      ╭─ ho ─────────────╮
                                                                      │               hi │
                                                                      ╰──────────────────╯

In [8]:

Platform

Click to expand

What platform (Win/Linux/Mac) are you running on? What terminal software are you using?

I may ask you to copy and paste the output of the following commands. It may save some time if you do it now.

If you're using Rich in a terminal:

python -m rich.diagnose
pip freeze | grep rich

If you're using Rich in a Jupyter Notebook, run the following snippet in a cell and paste the output in your bug report.

╭───────────────────────── <class 'rich.console.Console'> ─────────────────────────╮
│ A high level console interface.                                                  │
│                                                                                  │
│ ╭──────────────────────────────────────────────────────────────────────────────╮ │
│ │ <console width=204 ColorSystem.TRUECOLOR>                                    │ │
│ ╰──────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                  │
│     color_system = 'truecolor'                                                   │
│         encoding = 'utf-8'                                                       │
│             file = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'> │
│           height = 62                                                            │
│    is_alt_screen = False                                                         │
│ is_dumb_terminal = False                                                         │
│   is_interactive = True                                                          │
│       is_jupyter = False                                                         │
│      is_terminal = True                                                          │
│   legacy_windows = False                                                         │
│         no_color = False                                                         │
│          options = ConsoleOptions(                                               │
│                        size=ConsoleDimensions(width=204, height=62),             │
│                        legacy_windows=False,                                     │
│                        min_width=1,                                              │
│                        max_width=204,                                            │
│                        is_terminal=True,                                         │
│                        encoding='utf-8',                                         │
│                        max_height=62,                                            │
│                        justify=None,                                             │
│                        overflow=None,                                            │
│                        no_wrap=False,                                            │
│                        highlight=None,                                           │
│                        markup=None,                                              │
│                        height=None                                               │
│                    )                                                             │
│            quiet = False                                                         │
│           record = False                                                         │
│         safe_box = True                                                          │
│             size = ConsoleDimensions(width=204, height=62)                       │
│        soft_wrap = False                                                         │
│           stderr = False                                                         │
│            style = None                                                          │
│         tab_size = 8                                                             │
│            width = 204                                                           │
╰──────────────────────────────────────────────────────────────────────────────────╯
╭─── <class 'rich._windows.WindowsConsoleFeatures'> ────╮
│ Windows features available.                           │
│                                                       │
│ ╭───────────────────────────────────────────────────╮ │
│ │ WindowsConsoleFeatures(vt=False, truecolor=False) │ │
│ ╰───────────────────────────────────────────────────╯ │
│                                                       │
│ truecolor = False                                     │
│        vt = False                                     │
╰───────────────────────────────────────────────────────╯
╭────── Environment Variables ───────╮
│ {                                  │
│     'TERM': 'xterm-256color',      │
│     'COLORTERM': 'truecolor',      │
│     'CLICOLOR': None,              │
│     'NO_COLOR': None,              │
│     'TERM_PROGRAM': 'iTerm.app',   │
│     'COLUMNS': None,               │
│     'LINES': '62',                 │
│     'JUPYTER_COLUMNS': None,       │
│     'JUPYTER_LINES': None,         │
│     'JPY_PARENT_PID': None,        │
│     'VSCODE_VERBOSE_LOGGING': None │
│ }                                  │
╰────────────────────────────────────╯
platform="Darwin"

NorthIsUp avatar Feb 26 '25 05:02 NorthIsUp

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

github-actions[bot] avatar Feb 26 '25 05:02 github-actions[bot]

example test

def test_with_justify() -> None:
    panel = Panel(
        "Hello, World",
        title="title",
        subtitle="subtitle",
        title_align="right",
    )
    console = Console(
        file=io.StringIO(),
        width=50,
        height=20,
        legacy_windows=False,
        force_terminal=True,
        color_system="truecolor",
    )
    console.print(panel, justify="right")

    result = cleandoc(console.file.getvalue())
    expected = cleandoc("""
        ╭────── title ─╮
        │ Hello, World │
        ╰── subtitle ──╯
        """)
    assert result == expected

NorthIsUp avatar Feb 26 '25 06:02 NorthIsUp

Hey, I've taken a look at the issue and it appears to stem from containers.justify (specifically lines 139-142, where the trailing whitespace gets mistakenly rstrip'd and then padded to the beginning of the segment. If you need a fix: I've found that changing the line "line.rstrip()" to "line[:-1].rstrip()" prevents this behavior, and, at least in the case of the example you gave, solves the issue.

This isn't an elegant solution, but seeing as the titles are padded with whitespace it may be "right." Checking tests, I don't see that this introduces regressions covered by the test. If @willmcgugan doesn't have an issue with it, I'll submit a pull request introducing the change.

BenRachmiel avatar Mar 02 '25 21:03 BenRachmiel

glad you found it! I spent about an hour looking for the cause but I'm not familiar with the code base.

NorthIsUp avatar Mar 03 '25 21:03 NorthIsUp