Skip to content

ANSI stream state (SGR colors, OSC 8 hyperlinks) crossing line boundaries bleeds into box borders and padding #78

Description

@Delta456

Description

SGR colors and OSC 8 hyperlinks are stream state: once opened, they stay active across newlines until explicitly closed. The renderer assembles every box row independently, surrounding each content line with border glyphs and padding — but nothing closes/re-opens ANSI state at row boundaries. Any style span that crosses a line boundary therefore leaks into the box chrome.

Three manifestations, all from well-formed input:

1. Wrapping splits a colored span

b := box.NewBox().WrapLimit(12)
out, _ := b.Render("", "\x1b[32mgreen green green green green\x1b[0m tail")
row1: "│\x1b[32mgreen green│"      ← right border renders green
row2: "│green green│"              ← BOTH borders and padding green
row3: "│green\x1b[0m tail │"       ← left border green

The input span was properly opened and closed; the library's own wrap placed border glyphs inside it.

2. User content with SGR spanning its own newlines

b.Render("", "\x1b[31mred one\nred two\x1b[0m plain")

Row 1's padding + right border and row 2's left border render red.

3. OSC 8 hyperlink wrapped across lines

link := "\x1b]8;;https://example.com\x1b\\click here for the documentation\x1b]8;;\x1b\\"
box.NewBox().WrapLimit(12).Render("", link)

The link opens on row 1 and closes on row 4 — the borders and padding in between are inside the hyperlink. In terminals with OSC 8 support (iTerm2, Kitty, WezTerm), hovering/clicking the box border activates the URL.

Related inconsistency (same root cause)

When Color/ContentColor is set, each chrome segment ends in its own SGR reset, which truncates the user's spanning color instead — continuation lines silently lose their color. Whether the bug manifests as "chrome styled" or "user color dropped" depends on unrelated configuration.

Expected

Every rendered row is self-contained: styles/hyperlinks still open at the end of a line are closed there and re-opened at the start of the next line, so the author's styling spans lines without ever touching the borders.

Environment

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions