Track strikethrough (SGR 9) so it is not dropped across highlighted tokens

The `Attributes` ANSI style tracker in `src/vscreen.rs` declares, initializes,
clears (in `sgr_reset`), and re-emits (in `Display`) a `strike` field
documented as `ON: ^[9m / OFF: ^[29m`, but `update_with_sgr()` had no match
arm for SGR 9 (set strikethrough) or 29 (clear strikethrough). As a result
`strike` was only ever cleared, never set.

Because bat re-applies the tracked input ANSI style before each highlighted
text run (nu_ansi_term appends a full reset after every token), attributes
that are tracked — bold, dim, italic, underline — survive across tokens,
while strikethrough was silently dropped after the first token. This path is
active by default (`--strip-ansi`/`--sanitize` default to `never`).

Add the missing `9` and `29` arms, mirroring the sibling underline (4/24) and
italic (3/23) arms, so strikethrough is tracked and re-emitted like every
other supported attribute.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
mikehasaandClaude Opus 4.8 committed 2026-09-22 05:15:31 -07:00
1 parent 7323a7514f
commit 156ef1d2f4
3 files changed
+49 -3

No files matched your search

+19
View File
@@ -3355,6 +3355,25 @@ fn ansi_sgr_joins_attributes_when_wrapped() {
.stderr("");
}
// Ensure that strikethrough (SGR 9) is tracked like the other attributes, so it is
// re-emitted (and therefore preserved) across a wrap boundary instead of being dropped.
#[test]
fn ansi_sgr_strike_joins_attributes_when_wrapped() {
bat()
.arg("--paging=never")
.arg("--color=never")
.arg("--terminal-width=20")
.arg("--wrap=character")
.arg("--decorations=always")
.arg("--style=plain")
.write_stdin("\x1B[33mColor. \x1B[9mStrike.......Struck+color.\n")
.assert()
.success()
.stdout("\x1B[33m\x1B[33mColor. \x1B[9m\x1B[33m\x1B[9mStrike.......\n\x1B[33m\x1B[9mStruck+color.\n")
// FIXME: ~~~~~~~~ ~~~~~~~~~~~~~~~ should not be emitted twice.
.stderr("");
}
#[test]
fn ignored_suffix_arg() {
bat()