From 3a673aff6320caf34a7746b111f0b5f461578b96 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sun, 2 Mar 2025 06:27:23 +0100 Subject: [PATCH] Apply fish_color_search_match foreground only if explicit Historically, up-arrow search matches have been highlighted by 1. using the usual foreground (from syntax highlighting) 2. using the background from $fish_color_search_match Commit 9af6a64fd2 (Fix bad contrast in search match highlighting, 2024-04-15) broke this by also applying the foreground from $fish_color_search_match. As reported on gitter, there is a meaningful scenario where the foreground from syntax highlighting should not be overwritten: set fish_color_search_match --reverse this copies the foreground from syntax highlighting to the background. Since commit 9af6a64fd2 overwrites the foreground highlight, the resulting background will be monocolored (black in my case) instead of whatever is the syntax-colored foreground. FWIW the reversed foreground will always be monocolored, because we have always done 2. Let's unbreak this scenario by using the foreground from fish_color_search_match only if it's explicitly set (like we do since 9af6a64fd2). This is hacky because an empty color is normally the same as "normal", but it gets us closer to historical behavior. In future we should try to come up with a better approach to color blending/transparency. (cherry picked from commit b6269438e9e9424013d59cac39eea7d65de8885e) --- src/output.rs | 13 +++++++++---- src/reader.rs | 10 +++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/output.rs b/src/output.rs index 8833df4a0..740e5ba84 100644 --- a/src/output.rs +++ b/src/output.rs @@ -1,5 +1,5 @@ // Generic output functions. -use crate::color::RgbColor; +use crate::color::{self, RgbColor}; use crate::common::{self, wcs2string_appending}; use crate::curses::{self, tparm1, Term}; use crate::env::EnvVar; @@ -493,6 +493,14 @@ pub fn best_color(candidates: &[RgbColor], support: ColorSupport) -> RgbColor { /// In particular, the argument parsing still isn't fully capable. #[allow(clippy::collapsible_else_if)] pub fn parse_color(var: &EnvVar, is_background: bool) -> RgbColor { + let mut result = parse_color_maybe_none(var, is_background); + if result.is_none() { + result.typ = color::Type::Normal; + } + result +} + +pub fn parse_color_maybe_none(var: &EnvVar, is_background: bool) -> RgbColor { let mut is_bold = false; let mut is_underline = false; let mut is_italics = false; @@ -551,9 +559,6 @@ pub fn parse_color(var: &EnvVar, is_background: bool) -> RgbColor { } let mut result = best_color(&candidates, get_color_support()); - if result.is_none() { - result = RgbColor::NORMAL; - } result.set_bold(is_bold); result.set_underline(is_underline); result.set_italics(is_italics); diff --git a/src/reader.rs b/src/reader.rs index ea8e4356c..324c9e71f 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -88,6 +88,7 @@ use crate::nix::isatty; use crate::operation_context::{get_bg_context, OperationContext}; use crate::output::parse_color; +use crate::output::parse_color_maybe_none; use crate::output::Outputter; use crate::pager::{PageRendering, Pager, SelectionMotion}; use crate::panic::AT_EXIT; @@ -1499,8 +1500,15 @@ fn paint_layout(&mut self, reason: &wstr, is_final_rendering: bool) { range.end = colors.len(); } + let explicit_foreground = self + .vars() + .get_unless_empty(L!("fish_color_search_match")) + .is_some_and(|var| !parse_color_maybe_none(&var, false).is_none()); + for color in &mut colors[range] { - color.foreground = HighlightRole::search_match; + if explicit_foreground { + color.foreground = HighlightRole::search_match; + } color.background = HighlightRole::search_match; } }