From eaed50dbf621e18a9e71c92d045ab46eb68da3ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Wed, 20 Nov 2024 20:04:41 +0100 Subject: [PATCH] Improve handling of IRC color code (0x03) without colors afterwards (#435) 0x03 without a color code following should reset the current bg and fg colors. We can't reset just the colors without also resetting the formatting, for now reset colors + formatting. --- CHANGELOG.md | 2 ++ crates/libtiny_tui/src/msg_area/line.rs | 6 +++++- crates/libtiny_wire/src/formatting.rs | 21 +++++++++++++-------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8947b961..ab1b2e1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Unreleased - Improve nick matching to avoid highlighting message incorrectly. (#430) +- Fix resetting message color when a color prefix (0x03) is not followed by a + color code. (#434) # 2024/01/01: 0.12.0 diff --git a/crates/libtiny_tui/src/msg_area/line.rs b/crates/libtiny_tui/src/msg_area/line.rs index 30bc2f1c..bedde36b 100644 --- a/crates/libtiny_tui/src/msg_area/line.rs +++ b/crates/libtiny_tui/src/msg_area/line.rs @@ -156,7 +156,11 @@ impl Line { self.set_message_style(SegStyle::Fixed(Style { fg: bg, bg: fg })); } } - IrcFormatEvent::Reset => { + // TODO: ResetColors should only reset the colors and not the formatting. + // However we don't store the current formatting and we can't apply formatting to + // a color from the current color scheme (e.g. `SegStyle::UserMsg`). For now reset + // the colors and formatting. + IrcFormatEvent::ResetColors | IrcFormatEvent::Reset => { self.set_message_style(SegStyle::UserMsg); } } diff --git a/crates/libtiny_wire/src/formatting.rs b/crates/libtiny_wire/src/formatting.rs index 753a928a..cec8c1bd 100644 --- a/crates/libtiny_wire/src/formatting.rs +++ b/crates/libtiny_wire/src/formatting.rs @@ -30,10 +30,13 @@ pub enum IrcFormatEvent<'a> { bg: Option, }, - /// Reverse current background and foreground + /// Reverse current background and foreground colors. ReverseColor, - /// Reset formatting to the default + /// Reset background and foreground colors to the defaults. + ResetColors, + + /// Reset formatting to the default. Reset, } @@ -325,12 +328,10 @@ impl<'a> Iterator for FormatEventParser<'a> { CHAR_COLOR => { self.bump(1); - match self.parse_color() { - Some((fg, bg)) => return Some(IrcFormatEvent::Color { fg, bg }), - None => { - // Just skip the control char - } - } + return match self.parse_color() { + Some((fg, bg)) => Some(IrcFormatEvent::Color { fg, bg }), + None => Some(IrcFormatEvent::ResetColors), + }; } CHAR_HEX_COLOR => { @@ -389,6 +390,7 @@ pub fn remove_irc_control_chars(str: &str) -> String { | IrcFormatEvent::Monospace | IrcFormatEvent::Color { .. } | IrcFormatEvent::ReverseColor + | IrcFormatEvent::ResetColors | IrcFormatEvent::Reset => {} IrcFormatEvent::Text(text) => s.push_str(text), } @@ -431,6 +433,7 @@ fn test_parse_text_2() { let s = "a\x03"; let mut parser = parse_irc_formatting(s); assert_eq!(parser.next(), Some(IrcFormatEvent::Text("a"))); + assert_eq!(parser.next(), Some(IrcFormatEvent::ResetColors)); assert_eq!(parser.next(), None); } @@ -439,6 +442,7 @@ fn test_parse_text_3() { let s = "a\x03b"; let mut parser = parse_irc_formatting(s); assert_eq!(parser.next(), Some(IrcFormatEvent::Text("a"))); + assert_eq!(parser.next(), Some(IrcFormatEvent::ResetColors)); assert_eq!(parser.next(), Some(IrcFormatEvent::Text("b"))); assert_eq!(parser.next(), None); } @@ -511,6 +515,7 @@ fn test_parse_text_5() { let s = "\x03,a"; let mut parser = parse_irc_formatting(s); + assert_eq!(parser.next(), Some(IrcFormatEvent::ResetColors)); assert_eq!(parser.next(), Some(IrcFormatEvent::Text(",a"))); assert_eq!(parser.next(), None); }