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
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
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
Row 1's padding + right border and row 2's left border render red.
3. OSC 8 hyperlink wrapped across lines
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/ContentColoris 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
ansi.Wrapdoes not re-arm styles across wrapped lines)