Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Highlighting part of a link breaks it into two #3526

Open
2 tasks done
mgedmin opened this issue Oct 10, 2024 · 3 comments
Open
2 tasks done

[BUG] Highlighting part of a link breaks it into two #3526

mgedmin opened this issue Oct 10, 2024 · 3 comments

Comments

@mgedmin
Copy link

mgedmin commented Oct 10, 2024

Describe the bug

Styling part of a link breaks it. This is best illustrated with a code example:

import rich.console
import rich.text

console = rich.console.Console()
text = rich.text.Text(
    'This is a link',
    style=console.get_style('green').update_link('https://example.com'),
)
text.highlight_words(['link'], style='bold')
console.print(text)

now if you hover over "This is a link isn't it", you'll see that link and This is a isn't it are considered separate links.

Running FORCE_COLOR=1 python linkbug.py | xxd confirms that the differently-highlighted text parts get different link IDs (but the prefix and the suffix get the same one).

Platform

Click to expand

Ubuntu 24.04, with GNOME Terminal 3.52.0 using VTE 0.76.0 +BIDI +GNUTLS +ICU +SYSTEMD.

$ uv run python -m rich.diagnose
╭───────────────────────── <class 'rich.console.Console'> ─────────────────────────╮
│ A high level console interface.                                                  │
│                                                                                  │
│ ╭──────────────────────────────────────────────────────────────────────────────╮ │
│ │ <console width=126 ColorSystem.TRUECOLOR>                                    │ │
│ ╰──────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                  │
│     color_system = 'truecolor'                                                   │
│         encoding = 'utf-8'                                                       │
│             file = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'> │
│           height = 45                                                            │
│    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=126, height=45),             │
│                        legacy_windows=False,                                     │
│                        min_width=1,                                              │
│                        max_width=126,                                            │
│                        is_terminal=True,                                         │
│                        encoding='utf-8',                                         │
│                        max_height=45,                                            │
│                        justify=None,                                             │
│                        overflow=None,                                            │
│                        no_wrap=False,                                            │
│                        highlight=None,                                           │
│                        markup=None,                                              │
│                        height=None                                               │
│                    )                                                             │
│            quiet = False                                                         │
│           record = False                                                         │
│         safe_box = True                                                          │
│             size = ConsoleDimensions(width=126, height=45)                       │
│        soft_wrap = False                                                         │
│           stderr = False                                                         │
│            style = None                                                          │
│         tab_size = 8                                                             │
│            width = 126                                                           │
╰──────────────────────────────────────────────────────────────────────────────────╯
╭─── <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': None,          │
│     'COLUMNS': None,               │
│     'LINES': None,                 │
│     'JUPYTER_COLUMNS': None,       │
│     'JUPYTER_LINES': None,         │
│     'JPY_PARENT_PID': None,        │
│     'VSCODE_VERBOSE_LOGGING': None │
│ }                                  │
╰────────────────────────────────────╯
platform="Linux"

$ uv run pip freeze | grep rich
rich==13.7.1
Copy link

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

@mgedmin
Copy link
Author

mgedmin commented Oct 10, 2024

Removing the combined_style.copy() done in Style.__add__ fixes this bug for me. git blame is not very informative about why that .copy() was added there.

I'm seeing no new unit test failures in tox -e py312 if I remove the .copy(). (I'm seeing 6 failures in test_size_can_fall_back_to_std_descriptors, but they fail for me on git master with no local modifications as well.)

@mgedmin
Copy link
Author

mgedmin commented Oct 10, 2024

I now see that removing the .copy() in Style.__add__ makes unrelated links that point to the same URL and have the same style attributes get the same link ID:

import rich.console
import rich.text

console = rich.console.Console()
text = rich.text.Text(
    'This is a link',
    style=console.get_style('green').update_link('https://example.com'),
)
text.highlight_words(['link'], style='bold')
console.print(text)

text = rich.text.Text(
    'This is another link',
    style=console.get_style('green').update_link('https://example.com'),
)
console.print(text)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant