diff --git a/src/helper/item.rs b/src/helper/item.rs index 578c17f4..a4891dd2 100644 --- a/src/helper/item.rs +++ b/src/helper/item.rs @@ -230,18 +230,10 @@ impl SkimItem for DefaultSkimItem { // Flush normal content if any if !current_content.is_empty() { // Combine ANSI style with context base_style - let mut combined_base_style = base_style; - if let Some(bg) = context.base_style.bg { - combined_base_style = combined_base_style.bg(bg); - } - if let Some(fg) = context.base_style.fg - && base_style.fg.is_none() - { - combined_base_style = combined_base_style.fg(fg); - } - combined_base_style = - combined_base_style.add_modifier(context.base_style.add_modifier); - new_spans.push(Span::styled(current_content.clone(), combined_base_style)); + new_spans.push(Span::styled( + current_content.clone(), + base_style.patch(context.base_style), + )); current_content.clear(); } highlighted_content.push(ch); @@ -249,17 +241,10 @@ impl SkimItem for DefaultSkimItem { // Flush highlighted content if any if !highlighted_content.is_empty() { // Combine styles: use highlight bg, preserve ANSI fg and modifiers - let mut combined_style = base_style; - if let Some(bg) = context.style.bg { - combined_style = combined_style.bg(bg); - } - if let Some(fg) = context.style.fg - && base_style.fg.is_none() - { - combined_style = combined_style.fg(fg); - } - combined_style = combined_style.add_modifier(context.style.add_modifier); - new_spans.push(Span::styled(highlighted_content.clone(), combined_style)); + new_spans.push(Span::styled( + highlighted_content.clone(), + base_style.patch(context.matched_syle), + )); highlighted_content.clear(); } current_content.push(ch); @@ -270,31 +255,14 @@ impl SkimItem for DefaultSkimItem { // Flush remaining content if !current_content.is_empty() { // Combine ANSI style with context base_style - let mut combined_base_style = base_style; - if let Some(bg) = context.base_style.bg { - combined_base_style = combined_base_style.bg(bg); - } - if let Some(fg) = context.base_style.fg - && base_style.fg.is_none() - { - combined_base_style = combined_base_style.fg(fg); - } - combined_base_style = combined_base_style.add_modifier(context.base_style.add_modifier); - new_spans.push(Span::styled(current_content, combined_base_style)); + new_spans.push(Span::styled(current_content, base_style.patch(context.base_style))); } if !highlighted_content.is_empty() { // Combine styles: use highlight bg, preserve ANSI fg and modifiers - let mut combined_style = base_style; - if let Some(bg) = context.style.bg { - combined_style = combined_style.bg(bg); - } - if let Some(fg) = context.style.fg - && base_style.fg.is_none() - { - combined_style = combined_style.fg(fg); - } - combined_style = combined_style.add_modifier(context.style.add_modifier); - new_spans.push(Span::styled(highlighted_content, combined_style)); + new_spans.push(Span::styled( + highlighted_content, + base_style.patch(context.matched_syle), + )); } } @@ -327,45 +295,15 @@ impl SkimItem for DefaultSkimItem { if !before.is_empty() { // Combine ANSI style with context base_style - let mut combined_base_style = base_style; - if let Some(bg) = context.base_style.bg { - combined_base_style = combined_base_style.bg(bg); - } - if let Some(fg) = context.base_style.fg - && base_style.fg.is_none() - { - combined_base_style = combined_base_style.fg(fg); - } - combined_base_style = combined_base_style.add_modifier(context.base_style.add_modifier); - new_spans.push(Span::styled(before, combined_base_style)); + new_spans.push(Span::styled(before, base_style.patch(context.base_style))); } if !highlighted.is_empty() { - // Combine styles: use highlight bg, preserve ANSI fg and modifiers - let mut combined_style = base_style; - if let Some(bg) = context.style.bg { - combined_style = combined_style.bg(bg); - } - if let Some(fg) = context.style.fg - && base_style.fg.is_none() - { - combined_style = combined_style.fg(fg); - } - combined_style = combined_style.add_modifier(context.style.add_modifier); - new_spans.push(Span::styled(highlighted, combined_style)); + // Combine ANSI style with context matched_syle + new_spans.push(Span::styled(highlighted, base_style.patch(context.matched_syle))); } if !after.is_empty() { // Combine ANSI style with context base_style - let mut combined_base_style = base_style; - if let Some(bg) = context.base_style.bg { - combined_base_style = combined_base_style.bg(bg); - } - if let Some(fg) = context.base_style.fg - && base_style.fg.is_none() - { - combined_base_style = combined_base_style.fg(fg); - } - combined_base_style = combined_base_style.add_modifier(context.base_style.add_modifier); - new_spans.push(Span::styled(after, combined_base_style)); + new_spans.push(Span::styled(after, base_style.patch(context.base_style))); } } @@ -403,70 +341,21 @@ impl SkimItem for DefaultSkimItem { if !before.is_empty() { // Combine ANSI style with context base_style - let mut combined_base_style = base_style; - if let Some(bg) = context.base_style.bg { - combined_base_style = combined_base_style.bg(bg); - } - if let Some(fg) = context.base_style.fg - && base_style.fg.is_none() - { - combined_base_style = combined_base_style.fg(fg); - } - combined_base_style = combined_base_style.add_modifier(context.base_style.add_modifier); - new_spans.push(Span::styled(before, combined_base_style)); + new_spans.push(Span::styled(before, base_style.patch(context.base_style))); } if !highlighted.is_empty() { - // Combine styles: use highlight bg, preserve ANSI fg and modifiers - let mut combined_style = base_style; - if let Some(bg) = context.style.bg { - combined_style = combined_style.bg(bg); - } - if let Some(fg) = context.style.fg - && base_style.fg.is_none() - { - combined_style = combined_style.fg(fg); - } - combined_style = combined_style.add_modifier(context.style.add_modifier); - new_spans.push(Span::styled(highlighted, combined_style)); + // Combine ANSI style with context matched_syle + new_spans.push(Span::styled(highlighted, base_style.patch(context.matched_syle))); } if !after.is_empty() { // Combine ANSI style with context base_style - let mut combined_base_style = base_style; - if let Some(bg) = context.base_style.bg { - combined_base_style = combined_base_style.bg(bg); - } - if let Some(fg) = context.base_style.fg - && base_style.fg.is_none() - { - combined_base_style = combined_base_style.fg(fg); - } - combined_base_style = combined_base_style.add_modifier(context.base_style.add_modifier); - new_spans.push(Span::styled(after, combined_base_style)); + new_spans.push(Span::styled(after, base_style.patch(context.base_style))); } } Line::from(new_spans) } - crate::Matches::None => { - // No highlighting needed, but apply base_style to all spans - let styled_spans: Vec = all_spans - .into_iter() - .map(|span| { - let mut combined_style = span.style; - if let Some(bg) = context.base_style.bg { - combined_style = combined_style.bg(bg); - } - if let Some(fg) = context.base_style.fg - && span.style.fg.is_none() - { - combined_style = combined_style.fg(fg); - } - combined_style = combined_style.add_modifier(context.base_style.add_modifier); - Span::styled(span.content, combined_style) - }) - .collect(); - Line::from(styled_spans) - } + crate::Matches::None => Line::from(all_spans), } } else { // No ANSI mapping needed, use text as-is @@ -706,7 +595,7 @@ mod test { matches: Matches::CharRange(6, 10), container_width: 80, base_style: Style::default(), - style: Style::default().fg(Color::Yellow), + matched_syle: Style::default().fg(Color::Yellow), }; // display() should map the match positions back to the original ANSI text @@ -745,7 +634,7 @@ mod test { matches: Matches::CharIndices(vec![1, 2]), container_width: 80, base_style: Style::default(), - style: Style::default().fg(Color::Yellow), + matched_syle: Style::default().fg(Color::Yellow), }; // display() should map these to positions 6,7 in original text @@ -815,7 +704,7 @@ mod test { matches: Matches::CharIndices(vec![0]), container_width: 80, base_style: Style::default(), - style: Style::default().bg(Color::Yellow), + matched_syle: Style::default().bg(Color::Yellow), }; let line = item.display(context); @@ -854,7 +743,7 @@ mod test { matches: Matches::CharRange(1, 3), container_width: 80, base_style: Style::default(), - style: Style::default().bg(Color::Yellow), + matched_syle: Style::default().bg(Color::Yellow), }; let line = item.display(context); @@ -895,7 +784,7 @@ mod test { matches: Matches::ByteRange(1, 3), container_width: 80, base_style: Style::default(), - style: Style::default().bg(Color::Yellow), + matched_syle: Style::default().bg(Color::Yellow), }; let line = item.display(context); diff --git a/src/lib.rs b/src/lib.rs index acab914e..6f5ed20f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -124,7 +124,7 @@ pub struct DisplayContext { /// The base style to apply to non-matched portions pub base_style: Style, /// The style to apply to matched portions - pub style: Style, + pub matched_syle: Style, } impl DisplayContext { @@ -144,7 +144,7 @@ impl DisplayContext { res.push_span(Span::styled(span_content.collect::(), self.base_style)); let highlighted_char = chars.next().unwrap_or_default().to_string(); - res.push_span(Span::styled(highlighted_char, self.style)); + res.push_span(Span::styled(highlighted_char, self.base_style.patch(self.matched_syle))); prev_index = index + 1; } res.push_span(Span::styled(chars.collect::(), self.base_style)); @@ -161,7 +161,7 @@ impl DisplayContext { )); let highlighted_text = chars.by_ref().take(*end - *start).collect::(); - res.push_span(Span::styled(highlighted_text, self.style)); + res.push_span(Span::styled(highlighted_text, self.base_style.patch(self.matched_syle))); res.push_span(Span::styled(chars.collect::(), self.base_style)); res } @@ -175,7 +175,7 @@ impl DisplayContext { let highlighted_bytes = bytes.by_ref().take(*end - *start).collect(); let highlighted_text = String::from_utf8(highlighted_bytes).unwrap(); - res.push_span(Span::styled(highlighted_text, self.style)); + res.push_span(Span::styled(highlighted_text, self.base_style.patch(self.matched_syle))); res.push_span(Span::styled( String::from_utf8(bytes.collect()).unwrap(), self.base_style, diff --git a/src/theme.rs b/src/theme.rs index 035989b5..95868c51 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -64,19 +64,9 @@ impl ColorTheme { } fn none() -> Self { - ColorTheme { - normal: Style::reset(), - matched: Style::reset(), - current: Style::reset(), - current_match: Style::reset(), - query: Style::reset(), - spinner: Style::reset().bold(), - info: Style::reset(), - prompt: Style::reset(), - cursor: Style::reset(), - selected: Style::reset(), - header: Style::reset(), - border: Style::reset(), + Self { + spinner: Style::default().bold(), + ..ColorTheme::default() } } @@ -91,19 +81,18 @@ impl ColorTheme { } fn default16() -> Self { - let bg = Color::Black; let base = ColorTheme::none(); ColorTheme { - matched: base.matched.fg(Color::Green).bg(bg), - current: base.current.fg(Color::Yellow).bg(bg), - current_match: base.current_match.fg(Color::Green).bg(bg), - spinner: base.spinner.fg(Color::Green).bg(bg), - info: base.info.fg(Color::White).bg(bg), - prompt: base.prompt.fg(Color::Blue).bg(bg), - cursor: base.cursor.fg(Color::Red).bg(bg), - selected: base.selected.fg(Color::Magenta).bg(bg), - header: base.header.fg(Color::Cyan).bg(bg), - border: base.border.fg(Color::Black).bg(bg), + matched: base.matched.fg(Color::Green), + current: base.current.fg(Color::Yellow), + current_match: base.current_match.fg(Color::Green), + spinner: base.spinner.fg(Color::Green), + info: base.info.fg(Color::White), + prompt: base.prompt.fg(Color::Blue), + cursor: base.cursor.fg(Color::Red), + selected: base.selected.fg(Color::Magenta), + header: base.header.fg(Color::Cyan), + border: base.border.fg(Color::Black), ..base } } @@ -112,7 +101,7 @@ impl ColorTheme { let base = ColorTheme::none(); ColorTheme { matched: base.matched.fg(Color::Indexed(108)).bg(Color::Indexed(0)), - current: base.current.fg(Color::Indexed(254)).bg(Color::Indexed(236)), + current: base.current.bg(Color::Indexed(236)), current_match: base.current_match.fg(Color::Indexed(151)).bg(Color::Indexed(236)), spinner: base.spinner.fg(Color::Indexed(148)), info: base.info.fg(Color::Indexed(144)), @@ -129,7 +118,7 @@ impl ColorTheme { let base = ColorTheme::none(); ColorTheme { matched: base.matched.fg(Color::Indexed(234)).bg(Color::Indexed(186)), - current: base.current.fg(Color::Indexed(254)).bg(Color::Indexed(236)), + current: base.current.bg(Color::Indexed(236)), current_match: base.current_match.fg(Color::Indexed(234)).bg(Color::Indexed(186)), spinner: base.spinner.fg(Color::Indexed(148)), info: base.info.fg(Color::Indexed(144)), @@ -146,7 +135,7 @@ impl ColorTheme { let base = ColorTheme::none(); ColorTheme { matched: base.matched.fg(Color::Indexed(0)).bg(Color::Indexed(220)), - current: base.current.fg(Color::Indexed(237)).bg(Color::Indexed(251)), + current: base.current.bg(Color::Indexed(251)), current_match: base.current_match.fg(Color::Indexed(66)).bg(Color::Indexed(251)), spinner: base.spinner.fg(Color::Indexed(65)), info: base.info.fg(Color::Indexed(101)), @@ -206,6 +195,8 @@ impl ColorTheme { (&name[..name.len() - 2], "u") } else if name.ends_with("_underline") || name.ends_with("-underline") { (&name[..name.len() - 10], "underline") + } else if name == "bg" { + ("", "bg") } else { (name, "fg") }; @@ -307,7 +298,7 @@ mod tests { let theme_16 = ColorTheme::default16(); assert_eq!(theme_16.matched.fg, Some(Color::Green)); - assert_eq!(theme_16.matched.bg, Some(Color::Black)); + assert_eq!(theme_16.matched.bg, None); let dark = ColorTheme::dark256(); assert_eq!(dark.matched.fg, Some(Color::Indexed(108))); diff --git a/src/tui/item_list.rs b/src/tui/item_list.rs index 9b511803..91d739d7 100644 --- a/src/tui/item_list.rs +++ b/src/tui/item_list.rs @@ -676,7 +676,7 @@ impl SkimWidget for ItemList { matches, container_width, base_style: if is_current { theme.current } else { theme.normal }, - style: if is_current { theme.current_match } else { theme.matched }, + matched_syle: if is_current { theme.current_match } else { theme.matched }, }); if !wrap { diff --git a/tests/issues.rs b/tests/issues.rs index 07ded584..be7a4af8 100644 --- a/tests/issues.rs +++ b/tests/issues.rs @@ -26,7 +26,7 @@ sk_test!(issue_547_null_match, "\\0Test Test Test", &[], { @capture[0] starts_with("> Test"); @capture[2] starts_with("> Test Test Test"); - @capture_colored[2] trim().eq("\u{1b}[38;5;161m>\u{1b}[38;5;168m \u{1b}[38;5;151m\u{1b}[48;5;236mTest\u{1b}[38;5;254m Test Test"); + @capture_colored[2] trim().eq("\u{1b}[38;5;161m>\u{1b}[38;5;168m \u{1b}[38;5;151m\u{1b}[48;5;236mTest\u{1b}[39m Test Test"); }); sk_test!(issue_xxx_null_delimiter_with_nth, "a\\0b\\0c", &["--delimiter", "'\\x00'", "--with-nth", "2"], {