aboutsummaryrefslogtreecommitdiff
path: root/src/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/protocol')
-rw-r--r--src/protocol/render_ansi.rs22
-rw-r--r--src/protocol/wire.rs19
2 files changed, 37 insertions, 4 deletions
diff --git a/src/protocol/render_ansi.rs b/src/protocol/render_ansi.rs
index 12606bff..3346bb9c 100644
--- a/src/protocol/render_ansi.rs
+++ b/src/protocol/render_ansi.rs
@@ -31,7 +31,7 @@ use std::io::Write;
use unicode_width::UnicodeWidthStr;
-use crate::protocol::{CellData, FrameData};
+use crate::protocol::{underline_style_from_modifier, CellData, FrameData};
/// Bytes produced by a [`BlitEncoder`] for one terminal frame.
pub(crate) struct EncodedBlit {
@@ -294,7 +294,13 @@ fn modifier_to_sgr_parts(val: u16) -> Vec<&'static str> {
parts.push("3");
}
if val & UNDERLINED != 0 {
- parts.push("4");
+ parts.push(match underline_style_from_modifier(val) {
+ 2 => "4:2",
+ 3 => "4:3",
+ 4 => "4:4",
+ 5 => "4:5",
+ _ => "4",
+ });
}
if val & SLOW_BLINK != 0 {
parts.push("5");
@@ -843,6 +849,18 @@ mod tests {
}
#[test]
+ fn build_sgr_preserves_curly_underline_style() {
+ let modifier = crate::protocol::modifier_to_u16(
+ crate::protocol::modifier_with_underline_style(ratatui::style::Modifier::UNDERLINED, 3),
+ );
+
+ assert_eq!(
+ build_sgr(0x00_00_00_00, 0x00_00_00_00, modifier),
+ "\x1b[0;4:3;39;49m"
+ );
+ }
+
+ #[test]
fn cells_equal_identical() {
let a = make_cell("A", 2, 1, 0);
let b = make_cell("A", 2, 1, 0);
diff --git a/src/protocol/wire.rs b/src/protocol/wire.rs
index 5f44691b..8225cb8c 100644
--- a/src/protocol/wire.rs
+++ b/src/protocol/wire.rs
@@ -426,7 +426,7 @@ pub struct CellData {
pub fg: u32,
/// Background color as a packed u32.
pub bg: u32,
- /// Bitmask of style modifiers (bold, italic, etc.).
+ /// Bitmask of style modifiers (bold, italic, etc.) plus Herdr extension bits.
pub modifier: u16,
/// Whether this cell should be skipped during diff-based rendering.
pub skip: bool,
@@ -729,15 +729,30 @@ fn u32_to_color(val: u32) -> ratatui::style::Color {
}
}
+const UNDERLINE_STYLE_SHIFT: u16 = 12;
+const UNDERLINE_STYLE_MASK: u16 = 0xF000;
+
/// Converts a ratatui `Modifier` bitmask to a u16 for wire transport.
pub(crate) fn modifier_to_u16(modifier: ratatui::style::Modifier) -> u16 {
modifier.bits()
}
+pub(crate) fn underline_style_from_modifier(modifier: u16) -> u8 {
+ ((modifier & UNDERLINE_STYLE_MASK) >> UNDERLINE_STYLE_SHIFT) as u8
+}
+
+pub(crate) fn modifier_with_underline_style(
+ modifier: ratatui::style::Modifier,
+ underline_style: u8,
+) -> ratatui::style::Modifier {
+ let bits = modifier.bits() | ((u16::from(underline_style) & 0x0F) << UNDERLINE_STYLE_SHIFT);
+ ratatui::style::Modifier::from_bits_retain(bits)
+}
+
/// Converts a u16 back to a ratatui `Modifier`.
#[cfg(test)]
fn u16_to_modifier(val: u16) -> ratatui::style::Modifier {
- ratatui::style::Modifier::from_bits_truncate(val)
+ ratatui::style::Modifier::from_bits_truncate(val & !UNDERLINE_STYLE_MASK)
}
// ---------------------------------------------------------------------------