mirror of
https://github.com/sharkdp/bat.git
synced 2026-10-30 10:06:12 +00:00
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:
1 parent
7323a7514f
commit
156ef1d2f4
3 files changed
+49
-3
No files matched your search
+29
-3
@@ -173,8 +173,10 @@ impl Attributes {
|
||||
2 => self.dim = "\x1B[2m".to_owned(),
|
||||
3 => self.italic = "\x1B[3m".to_owned(),
|
||||
4 => self.underline = "\x1B[4m".to_owned(),
|
||||
9 => self.strike = "\x1B[9m".to_owned(),
|
||||
23 => self.italic.clear(),
|
||||
24 => self.underline.clear(),
|
||||
29 => self.strike.clear(),
|
||||
22 => {
|
||||
self.bold.clear();
|
||||
self.dim.clear();
|
||||
@@ -1112,10 +1114,10 @@ mod tests {
|
||||
fn test_sgr_attributes_do_not_leak_into_wrong_field() {
|
||||
let mut attrs = crate::vscreen::Attributes::new();
|
||||
|
||||
// Bold, Dim, Italic, Underline, Foreground, Background
|
||||
// Bold, Dim, Italic, Underline, Strike, Foreground, Background
|
||||
attrs.update(EscapeSequence::CSI {
|
||||
raw_sequence: "\x1B[1;2;3;4;31;41m",
|
||||
parameters: "1;2;3;4;31;41",
|
||||
raw_sequence: "\x1B[1;2;3;4;9;31;41m",
|
||||
parameters: "1;2;3;4;9;31;41",
|
||||
intermediates: "",
|
||||
final_byte: "m",
|
||||
});
|
||||
@@ -1124,6 +1126,7 @@ mod tests {
|
||||
assert_eq!(attrs.dim, "\x1B[2m");
|
||||
assert_eq!(attrs.italic, "\x1B[3m");
|
||||
assert_eq!(attrs.underline, "\x1B[4m");
|
||||
assert_eq!(attrs.strike, "\x1B[9m");
|
||||
assert_eq!(attrs.foreground, "\x1B[31m");
|
||||
assert_eq!(attrs.background, "\x1B[41m");
|
||||
|
||||
@@ -1140,4 +1143,27 @@ mod tests {
|
||||
assert_eq!(attrs.foreground, "\x1B[94m");
|
||||
assert_eq!(attrs.background, "\x1B[103m");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sgr_strike_is_tracked_and_cleared() {
|
||||
let mut attrs = crate::vscreen::Attributes::new();
|
||||
|
||||
// Strikethrough on (SGR 9) must be tracked so it can be re-emitted.
|
||||
attrs.update(EscapeSequence::CSI {
|
||||
raw_sequence: "\x1B[9m",
|
||||
parameters: "9",
|
||||
intermediates: "",
|
||||
final_byte: "m",
|
||||
});
|
||||
assert_eq!(attrs.strike, "\x1B[9m");
|
||||
|
||||
// Strikethrough off (SGR 29) must clear it, just like italic (23) and underline (24).
|
||||
attrs.update(EscapeSequence::CSI {
|
||||
raw_sequence: "\x1B[29m",
|
||||
parameters: "29",
|
||||
intermediates: "",
|
||||
final_byte: "m",
|
||||
});
|
||||
assert_eq!(attrs.strike, "");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user