mirror of
https://github.com/lotabout/skim.git
synced 2026-09-10 07:16:23 -04:00
fix: correctly merge styles & do not reset them by default (#918)
This commit is contained in:
parent
2cfd33ccc9
commit
96a4c69646
|
|
@ -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<Span> = 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);
|
||||
|
|
|
|||
|
|
@ -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::<String>(), 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::<String>(), self.base_style));
|
||||
|
|
@ -161,7 +161,7 @@ impl DisplayContext {
|
|||
));
|
||||
let highlighted_text = chars.by_ref().take(*end - *start).collect::<String>();
|
||||
|
||||
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::<String>(), 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,
|
||||
|
|
|
|||
47
src/theme.rs
47
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)));
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"], {
|
||||
|
|
|
|||
Loading…
Reference in a new issue