Compare commits

...

13 Commits

Author SHA1 Message Date
Smit Barmase
e317217f3d fix highlight ranges for project search 2025-12-02 22:35:39 +05:30
Smit Barmase
3a75514e10 update when selection updates 2025-12-02 22:24:52 +05:30
Smit Barmase
bff0613f39 update only when is not dismissed 2025-12-02 20:40:18 +05:30
Smit Barmase
5cbbf98301 remove 2025-12-02 20:25:34 +05:30
Smit Barmase
4b9d8a4162 update active match correctly 2025-12-02 20:04:36 +05:30
Smit Barmase
ebdf720610 use arc 2025-12-02 19:44:51 +05:30
DarkMatter-999
bc9ed89ad8 feat: add active search match support for 'Gruvbox' themes 2025-12-02 17:59:41 +05:30
DarkMatter-999
55607b9493 feat: add active search match support for 'Ayu' themes 2025-12-02 17:59:25 +05:30
DarkMatter-999
0e3eca9b4b feat: add active search match support for 'One' themes 2025-12-02 17:59:05 +05:30
Smit Barmase
1f2196de5d import 2025-12-02 17:58:02 +05:30
Smit Barmase
f3a3c52c67 active background highlight 2025-12-02 17:47:01 +05:30
Smit Barmase
1fbb2e6703 rename 2025-12-02 17:37:14 +05:30
Smit Barmase
07a26c4607 traitify background highlight api 2025-12-02 17:31:53 +05:30
25 changed files with 297 additions and 150 deletions

View File

@@ -45,6 +45,7 @@
"tab.inactive_background": "#1f2127ff",
"tab.active_background": "#0d1016ff",
"search.match_background": "#5ac2fe66",
"search.active_match_background": "#ea570166",
"panel.background": "#1f2127ff",
"panel.focused_border": "#5ac1feff",
"pane.focused_border": null,
@@ -436,6 +437,7 @@
"tab.inactive_background": "#ececedff",
"tab.active_background": "#fcfcfcff",
"search.match_background": "#3b9ee566",
"search.active_match_background": "#f88b3666",
"panel.background": "#ececedff",
"panel.focused_border": "#3b9ee5ff",
"pane.focused_border": null,
@@ -827,6 +829,7 @@
"tab.inactive_background": "#353944ff",
"tab.active_background": "#242835ff",
"search.match_background": "#73cffe66",
"search.active_match_background": "#fd722b66",
"panel.background": "#353944ff",
"panel.focused_border": null,
"pane.focused_border": null,

View File

@@ -46,6 +46,7 @@
"tab.inactive_background": "#3a3735ff",
"tab.active_background": "#282828ff",
"search.match_background": "#83a59866",
"search.active_match_background": "#c09f3f66",
"panel.background": "#3a3735ff",
"panel.focused_border": "#83a598ff",
"pane.focused_border": null,
@@ -452,6 +453,7 @@
"tab.inactive_background": "#393634ff",
"tab.active_background": "#1d2021ff",
"search.match_background": "#83a59866",
"search.active_match_background": "#c9653666",
"panel.background": "#393634ff",
"panel.focused_border": "#83a598ff",
"pane.focused_border": null,
@@ -858,6 +860,7 @@
"tab.inactive_background": "#3b3735ff",
"tab.active_background": "#32302fff",
"search.match_background": "#83a59866",
"search.active_match_background": "#aea85166",
"panel.background": "#3b3735ff",
"panel.focused_border": null,
"pane.focused_border": null,
@@ -1264,6 +1267,7 @@
"tab.inactive_background": "#ecddb4ff",
"tab.active_background": "#fbf1c7ff",
"search.match_background": "#0b667866",
"search.active_match_background": "#ba2d1166",
"panel.background": "#ecddb4ff",
"panel.focused_border": null,
"pane.focused_border": null,
@@ -1670,6 +1674,7 @@
"tab.inactive_background": "#ecddb5ff",
"tab.active_background": "#f9f5d7ff",
"search.match_background": "#0b667866",
"search.active_match_background": "#dc351466",
"panel.background": "#ecddb5ff",
"panel.focused_border": null,
"pane.focused_border": null,
@@ -2076,6 +2081,7 @@
"tab.inactive_background": "#ecdcb3ff",
"tab.active_background": "#f2e5bcff",
"search.match_background": "#0b667866",
"search.active_match_background": "#d7331466",
"panel.background": "#ecdcb3ff",
"panel.focused_border": null,
"pane.focused_border": null,

View File

@@ -45,6 +45,7 @@
"tab.inactive_background": "#2f343eff",
"tab.active_background": "#282c33ff",
"search.match_background": "#74ade866",
"search.active_match_background": "#e8af7466",
"panel.background": "#2f343eff",
"panel.focused_border": null,
"pane.focused_border": null,
@@ -448,6 +449,7 @@
"tab.inactive_background": "#ebebecff",
"tab.active_background": "#fafafaff",
"search.match_background": "#5c79e266",
"search.active_match_background": "#d0a92366",
"panel.background": "#ebebecff",
"panel.focused_border": null,
"pane.focused_border": null,

View File

@@ -2622,11 +2622,13 @@ impl SearchableItem for TextThreadEditor {
fn update_matches(
&mut self,
matches: &[Self::Match],
active_match_index: Option<usize>,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.editor
.update(cx, |editor, cx| editor.update_matches(matches, window, cx));
self.editor.update(cx, |editor, cx| {
editor.update_matches(matches, active_match_index, window, cx)
});
}
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {

View File

@@ -1017,11 +1017,13 @@ impl SearchableItem for DapLogView {
fn update_matches(
&mut self,
matches: &[Self::Match],
active_match_index: Option<usize>,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.editor
.update(cx, |e, cx| e.update_matches(matches, window, cx))
self.editor.update(cx, |e, cx| {
e.update_matches(matches, active_match_index, window, cx)
})
}
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {

View File

@@ -7,8 +7,8 @@ use anyhow::Result;
use collections::HashMap;
use dap::{CompletionItem, CompletionItemType, OutputEvent};
use editor::{
Bias, CompletionProvider, Editor, EditorElement, EditorMode, EditorStyle, ExcerptId,
MultiBufferOffset, SizingBehavior,
BackgroundHighlight, Bias, CompletionProvider, Editor, EditorElement, EditorMode, EditorStyle,
ExcerptId, MultiBufferOffset, SizingBehavior,
};
use fuzzy::StringMatchCandidate;
use gpui::{
@@ -252,10 +252,9 @@ impl Console {
let start_offset = range.start;
let range = buffer.anchor_after(MultiBufferOffset(range.start))
..buffer.anchor_before(MultiBufferOffset(range.end));
console.highlight_background_key::<ConsoleAnsiHighlight>(
console.highlight_background_key::<ConsoleAnsiHighlight, _>(
start_offset,
&[range],
color_fetcher(color),
BackgroundHighlight::new(&[range], color_fetcher(color)),
cx,
);
}

View File

@@ -726,7 +726,63 @@ impl EditorActionId {
// type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor;
// type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>;
type BackgroundHighlight = (fn(&Theme) -> Hsla, Arc<[Range<Anchor>]>);
pub trait BackgroundHighlightHandle: 'static + Send + Sync {
fn ranges(&self) -> &[Range<Anchor>];
fn color_for_range(&self, index: usize, theme: &Theme) -> Hsla;
}
pub struct BackgroundHighlight {
ranges: Arc<[Range<Anchor>]>,
color_fetcher: fn(&Theme) -> Hsla,
}
impl BackgroundHighlight {
pub fn new(ranges: &[Range<Anchor>], color_fetcher: fn(&Theme) -> Hsla) -> Self {
Self {
ranges: Arc::from(ranges),
color_fetcher,
}
}
}
impl BackgroundHighlightHandle for BackgroundHighlight {
fn ranges(&self) -> &[Range<Anchor>] {
&self.ranges
}
fn color_for_range(&self, _index: usize, theme: &Theme) -> Hsla {
(self.color_fetcher)(theme)
}
}
pub struct ActiveBackgroundHighlight {
pub ranges: Arc<[Range<Anchor>]>,
pub active_index: Option<usize>,
}
impl ActiveBackgroundHighlight {
pub fn new(ranges: &[Range<Anchor>], active_index: Option<usize>) -> Self {
Self {
ranges: Arc::from(ranges),
active_index,
}
}
}
impl BackgroundHighlightHandle for ActiveBackgroundHighlight {
fn ranges(&self) -> &[Range<Anchor>] {
&self.ranges
}
fn color_for_range(&self, index: usize, theme: &theme::Theme) -> gpui::Hsla {
if Some(index) == self.active_index {
theme.colors().search_active_match_background
} else {
theme.colors().search_match_background
}
}
}
type GutterHighlight = (fn(&App) -> Hsla, Vec<Range<Anchor>>);
#[derive(Default)]
@@ -1078,7 +1134,7 @@ pub struct Editor {
show_indent_guides: Option<bool>,
highlight_order: usize,
highlighted_rows: HashMap<TypeId, Vec<RowHighlight>>,
background_highlights: HashMap<HighlightKey, BackgroundHighlight>,
background_highlights: HashMap<HighlightKey, Arc<dyn BackgroundHighlightHandle>>,
gutter_highlights: HashMap<TypeId, GutterHighlight>,
scrollbar_marker_state: ScrollbarMarkerState,
active_indent_guides_state: ActiveIndentGuidesState,
@@ -6551,9 +6607,10 @@ impl Editor {
cx.new(|cx| Editor::for_multibuffer(excerpt_buffer, Some(project), window, cx));
workspace.add_item_to_active_pane(Box::new(editor.clone()), None, true, window, cx);
editor.update(cx, |editor, cx| {
editor.highlight_background::<Self>(
&ranges_to_highlight,
|theme| theme.colors().editor_highlighted_line_background,
editor.highlight_background::<Self, _>(
BackgroundHighlight::new(&ranges_to_highlight, |theme| {
theme.colors().editor_highlighted_line_background
}),
cx,
);
});
@@ -6950,14 +7007,16 @@ impl Editor {
}
}
this.highlight_background::<DocumentHighlightRead>(
&read_ranges,
|theme| theme.colors().editor_document_highlight_read_background,
this.highlight_background::<DocumentHighlightRead, _>(
BackgroundHighlight::new(&read_ranges, |theme| {
theme.colors().editor_document_highlight_read_background
}),
cx,
);
this.highlight_background::<DocumentHighlightWrite>(
&write_ranges,
|theme| theme.colors().editor_document_highlight_write_background,
this.highlight_background::<DocumentHighlightWrite, _>(
BackgroundHighlight::new(&write_ranges, |theme| {
theme.colors().editor_document_highlight_write_background
}),
cx,
);
cx.notify();
@@ -7063,9 +7122,10 @@ impl Editor {
.update_in(cx, |editor, _, cx| {
editor.clear_background_highlights::<SelectedTextHighlight>(cx);
if !match_ranges.is_empty() {
editor.highlight_background::<SelectedTextHighlight>(
&match_ranges,
|theme| theme.colors().editor_document_highlight_bracket_background,
editor.highlight_background::<SelectedTextHighlight, _>(
BackgroundHighlight::new(&match_ranges, |theme| {
theme.colors().editor_document_highlight_bracket_background
}),
cx,
)
}
@@ -16630,18 +16690,18 @@ impl Editor {
// Get all document highlights (both read and write)
let mut all_highlights = Vec::new();
if let Some((_, read_highlights)) = self
if let Some(read_highlights) = self
.background_highlights
.get(&HighlightKey::Type(TypeId::of::<DocumentHighlightRead>()))
{
all_highlights.extend(read_highlights.iter());
all_highlights.extend(read_highlights.ranges().iter());
}
if let Some((_, write_highlights)) = self
if let Some(write_highlights) = self
.background_highlights
.get(&HighlightKey::Type(TypeId::of::<DocumentHighlightWrite>()))
{
all_highlights.extend(write_highlights.iter());
all_highlights.extend(write_highlights.ranges().iter());
}
if all_highlights.is_empty() {
@@ -17448,9 +17508,10 @@ impl Editor {
},
);
}
editor.highlight_background::<Self>(
&ranges,
|theme| theme.colors().editor_highlighted_line_background,
editor.highlight_background::<Self, _>(
BackgroundHighlight::new(&ranges, |theme| {
theme.colors().editor_highlighted_line_background
}),
cx,
);
}
@@ -17617,8 +17678,8 @@ impl Editor {
this.clear_background_highlights::<DocumentHighlightRead>(cx);
let ranges = write_highlights
.iter()
.flat_map(|(_, ranges)| ranges.iter())
.chain(read_highlights.iter().flat_map(|(_, ranges)| ranges.iter()))
.flat_map(|h| h.ranges().iter())
.chain(read_highlights.iter().flat_map(|h| h.ranges().iter()))
.cloned()
.collect();
@@ -20876,9 +20937,10 @@ impl Editor {
}
pub fn set_search_within_ranges(&mut self, ranges: &[Range<Anchor>], cx: &mut Context<Self>) {
self.highlight_background::<SearchWithinRange>(
ranges,
|colors| colors.colors().editor_document_highlight_read_background,
self.highlight_background::<SearchWithinRange, _>(
BackgroundHighlight::new(ranges, |colors| {
colors.colors().editor_document_highlight_read_background
}),
cx,
)
}
@@ -20891,30 +20953,26 @@ impl Editor {
self.clear_background_highlights::<SearchWithinRange>(cx);
}
pub fn highlight_background<T: 'static>(
pub fn highlight_background<T: 'static, H: BackgroundHighlightHandle>(
&mut self,
ranges: &[Range<Anchor>],
color_fetcher: fn(&Theme) -> Hsla,
highlight: H,
cx: &mut Context<Self>,
) {
self.background_highlights.insert(
HighlightKey::Type(TypeId::of::<T>()),
(color_fetcher, Arc::from(ranges)),
);
self.background_highlights
.insert(HighlightKey::Type(TypeId::of::<T>()), Arc::new(highlight));
self.scrollbar_marker_state.dirty = true;
cx.notify();
}
pub fn highlight_background_key<T: 'static>(
pub fn highlight_background_key<T: 'static, H: BackgroundHighlightHandle>(
&mut self,
key: usize,
ranges: &[Range<Anchor>],
color_fetcher: fn(&Theme) -> Hsla,
highlight: H,
cx: &mut Context<Self>,
) {
self.background_highlights.insert(
HighlightKey::TypePlus(TypeId::of::<T>(), key),
(color_fetcher, Arc::from(ranges)),
Arc::new(highlight),
);
self.scrollbar_marker_state.dirty = true;
cx.notify();
@@ -20923,11 +20981,11 @@ impl Editor {
pub fn clear_background_highlights<T: 'static>(
&mut self,
cx: &mut Context<Self>,
) -> Option<BackgroundHighlight> {
) -> Option<Arc<dyn BackgroundHighlightHandle>> {
let text_highlights = self
.background_highlights
.remove(&HighlightKey::Type(TypeId::of::<T>()))?;
if !text_highlights.1.is_empty() {
if !text_highlights.ranges().is_empty() {
self.scrollbar_marker_state.dirty = true;
cx.notify();
}
@@ -21068,16 +21126,17 @@ impl Editor {
#[cfg(feature = "test-support")]
pub fn search_background_highlights(&mut self, cx: &mut Context<Self>) -> Vec<Range<Point>> {
use crate::items::BufferSearchHighlights;
let snapshot = self.buffer().read(cx).snapshot(cx);
let highlights = self
.background_highlights
.get(&HighlightKey::Type(TypeId::of::<
items::BufferSearchHighlights,
>()));
.get(&HighlightKey::Type(TypeId::of::<BufferSearchHighlights>()));
if let Some((_color, ranges)) = highlights {
ranges
if let Some(highlight) = highlights {
highlight
.ranges()
.iter()
.map(|range| range.start.to_point(&snapshot)..range.end.to_point(&snapshot))
.collect_vec()
@@ -21094,11 +21153,11 @@ impl Editor {
let read_highlights = self
.background_highlights
.get(&HighlightKey::Type(TypeId::of::<DocumentHighlightRead>()))
.map(|h| &h.1);
.map(|h| h.ranges());
let write_highlights = self
.background_highlights
.get(&HighlightKey::Type(TypeId::of::<DocumentHighlightWrite>()))
.map(|h| &h.1);
.map(|h| h.ranges());
let left_position = position.bias_left(buffer);
let right_position = position.bias_right(buffer);
read_highlights
@@ -21125,7 +21184,7 @@ impl Editor {
pub fn has_background_highlights<T: 'static>(&self) -> bool {
self.background_highlights
.get(&HighlightKey::Type(TypeId::of::<T>()))
.is_some_and(|(_, highlights)| !highlights.is_empty())
.is_some_and(|highlight| !highlight.ranges().is_empty())
}
/// Returns all background highlights for a given range.
@@ -21138,8 +21197,8 @@ impl Editor {
theme: &Theme,
) -> Vec<(Range<DisplayPoint>, Hsla)> {
let mut results = Vec::new();
for (color_fetcher, ranges) in self.background_highlights.values() {
let color = color_fetcher(theme);
for highlight in self.background_highlights.values() {
let ranges = highlight.ranges();
let start_ix = match ranges.binary_search_by(|probe| {
let cmp = probe
.end
@@ -21152,7 +21211,7 @@ impl Editor {
}) {
Ok(i) | Err(i) => i,
};
for range in &ranges[start_ix..] {
for (idx, range) in ranges[start_ix..].iter().enumerate() {
if range
.start
.cmp(&search_range.end, &display_snapshot.buffer_snapshot())
@@ -21161,6 +21220,7 @@ impl Editor {
break;
}
let color = highlight.color_for_range(start_ix + idx, theme);
let start = range.start.to_display_point(display_snapshot);
let end = range.end.to_display_point(display_snapshot);
results.push((start..end, color))

View File

@@ -16797,24 +16797,28 @@ fn test_highlighted_ranges(cx: &mut TestAppContext) {
let anchor_range =
|range: Range<Point>| buffer.anchor_after(range.start)..buffer.anchor_after(range.end);
editor.highlight_background::<Type1>(
&[
anchor_range(Point::new(2, 1)..Point::new(2, 3)),
anchor_range(Point::new(4, 2)..Point::new(4, 4)),
anchor_range(Point::new(6, 3)..Point::new(6, 5)),
anchor_range(Point::new(8, 4)..Point::new(8, 6)),
],
|_| Hsla::red(),
editor.highlight_background::<Type1, _>(
BackgroundHighlight::new(
&[
anchor_range(Point::new(2, 1)..Point::new(2, 3)),
anchor_range(Point::new(4, 2)..Point::new(4, 4)),
anchor_range(Point::new(6, 3)..Point::new(6, 5)),
anchor_range(Point::new(8, 4)..Point::new(8, 6)),
],
|_| Hsla::red(),
),
cx,
);
editor.highlight_background::<Type2>(
&[
anchor_range(Point::new(3, 2)..Point::new(3, 5)),
anchor_range(Point::new(5, 3)..Point::new(5, 6)),
anchor_range(Point::new(7, 4)..Point::new(7, 7)),
anchor_range(Point::new(9, 5)..Point::new(9, 8)),
],
|_| Hsla::green(),
editor.highlight_background::<Type2, _>(
BackgroundHighlight::new(
&[
anchor_range(Point::new(3, 2)..Point::new(3, 5)),
anchor_range(Point::new(5, 3)..Point::new(5, 6)),
anchor_range(Point::new(7, 4)..Point::new(7, 7)),
anchor_range(Point::new(9, 5)..Point::new(9, 8)),
],
|_| Hsla::green(),
),
cx,
);
@@ -23797,9 +23801,10 @@ async fn test_rename_with_duplicate_edits(cx: &mut TestAppContext) {
cx.update_editor(|editor, _, cx| {
let highlight_range = Point::new(0, 7)..Point::new(0, 10);
let highlight_range = highlight_range.to_anchors(&editor.buffer().read(cx).snapshot(cx));
editor.highlight_background::<DocumentHighlightRead>(
&[highlight_range],
|theme| theme.colors().editor_document_highlight_read_background,
editor.highlight_background::<DocumentHighlightRead, _>(
BackgroundHighlight::new(&[highlight_range], |theme| {
theme.colors().editor_document_highlight_read_background
}),
cx,
);
});
@@ -23875,9 +23880,10 @@ async fn test_rename_without_prepare(cx: &mut TestAppContext) {
cx.update_editor(|editor, _window, cx| {
let highlight_range = Point::new(0, 7)..Point::new(0, 10);
let highlight_range = highlight_range.to_anchors(&editor.buffer().read(cx).snapshot(cx));
editor.highlight_background::<DocumentHighlightRead>(
&[highlight_range],
|theme| theme.colors().editor_document_highlight_read_background,
editor.highlight_background::<DocumentHighlightRead, _>(
BackgroundHighlight::new(&[highlight_range], |theme| {
theme.colors().editor_document_highlight_read_background
}),
cx,
);
});
@@ -27123,9 +27129,10 @@ let result = variable * 2;",
.map(|range| range.clone().to_anchors(&buffer_snapshot))
.collect();
editor.highlight_background::<DocumentHighlightRead>(
&anchor_ranges,
|theme| theme.colors().editor_document_highlight_read_background,
editor.highlight_background::<DocumentHighlightRead, _>(
BackgroundHighlight::new(&anchor_ranges, |theme| {
theme.colors().editor_document_highlight_read_background
}),
cx,
);
});

View File

@@ -7083,7 +7083,7 @@ impl EditorElement {
);
}
for (background_highlight_id, (_, background_ranges)) in
for (background_highlight_id, background_highlight) in
background_highlights.iter()
{
let is_search_highlights = *background_highlight_id
@@ -7104,18 +7104,20 @@ impl EditorElement {
if is_symbol_occurrences {
color.fade_out(0.5);
}
let marker_row_ranges = background_ranges.iter().map(|range| {
let display_start = range
.start
.to_display_point(&snapshot.display_snapshot);
let display_end =
range.end.to_display_point(&snapshot.display_snapshot);
ColoredRange {
start: display_start.row(),
end: display_end.row(),
color,
}
});
let marker_row_ranges =
background_highlight.ranges().iter().map(|range| {
let display_start = range
.start
.to_display_point(&snapshot.display_snapshot);
let display_end = range
.end
.to_display_point(&snapshot.display_snapshot);
ColoredRange {
start: display_start.row(),
end: display_end.row(),
color,
}
});
marker_quads.extend(
scrollbar_layout
.marker_quads_for_ranges(marker_row_ranges, Some(1)),

View File

@@ -1,6 +1,6 @@
use crate::{
ActiveDiagnostic, Anchor, AnchorRangeExt, DisplayPoint, DisplayRow, Editor, EditorSettings,
EditorSnapshot, GlobalDiagnosticRenderer, Hover,
EditorSnapshot, GlobalDiagnosticRenderer, Hover, BackgroundHighlight,
display_map::{InlayOffset, ToDisplayPoint, is_invisible},
hover_links::{InlayHighlight, RangeInEditor},
movement::TextLayoutDetails,
@@ -516,9 +516,11 @@ fn show_hover(
editor.clear_background_highlights::<HoverState>(cx);
} else {
// Highlight the selected symbol using a background highlight
editor.highlight_background::<HoverState>(
&hover_highlights,
|theme| theme.colors().element_hover, // todo update theme
editor.highlight_background::<HoverState, _>(
BackgroundHighlight::new(
&hover_highlights,
|theme| theme.colors().element_hover, // todo update theme
),
cx,
);
}

View File

@@ -1,7 +1,7 @@
use crate::{
Anchor, Autoscroll, BufferSerialization, Editor, EditorEvent, EditorSettings, ExcerptId,
ExcerptRange, FormatTarget, MultiBuffer, MultiBufferSnapshot, NavigationData,
ReportEditorEvent, SearchWithinRange, SelectionEffects, ToPoint as _,
ActiveBackgroundHighlight, Anchor, Autoscroll, BufferSerialization, Editor, EditorEvent,
EditorSettings, ExcerptId, ExcerptRange, FormatTarget, MultiBuffer, MultiBufferSnapshot,
NavigationData, ReportEditorEvent, SearchWithinRange, SelectionEffects, ToPoint as _,
display_map::HighlightKey,
editor_settings::SeedQuerySetting,
persistence::{DB, SerializedEditor},
@@ -1470,8 +1470,8 @@ impl SearchableItem for Editor {
fn get_matches(&self, _window: &mut Window, _: &mut App) -> Vec<Range<Anchor>> {
self.background_highlights
.get(&HighlightKey::Type(TypeId::of::<BufferSearchHighlights>()))
.map_or(Vec::new(), |(_color, ranges)| {
ranges.iter().cloned().collect()
.map_or(Vec::new(), |highlight| {
highlight.ranges().iter().cloned().collect()
})
}
@@ -1487,17 +1487,17 @@ impl SearchableItem for Editor {
fn update_matches(
&mut self,
matches: &[Range<Anchor>],
active_match_index: Option<usize>,
_: &mut Window,
cx: &mut Context<Self>,
) {
let existing_range = self
.background_highlights
.get(&HighlightKey::Type(TypeId::of::<BufferSearchHighlights>()))
.map(|(_, range)| range.as_ref());
.map(|highlight| highlight.ranges());
let updated = existing_range != Some(matches);
self.highlight_background::<BufferSearchHighlights>(
matches,
|theme| theme.colors().search_match_background,
self.highlight_background::<BufferSearchHighlights, _>(
ActiveBackgroundHighlight::new(matches, active_match_index),
cx,
);
if updated {
@@ -1518,7 +1518,7 @@ impl SearchableItem for Editor {
if self.has_filtered_search_ranges() {
self.previous_search_ranges = self
.clear_background_highlights::<SearchWithinRange>(cx)
.map(|(_, ranges)| ranges)
.map(|h| Arc::from(h.ranges()))
}
if let Some(range) = enabled {
@@ -1734,8 +1734,8 @@ impl SearchableItem for Editor {
let search_within_ranges = self
.background_highlights
.get(&HighlightKey::Type(TypeId::of::<SearchWithinRange>()))
.map_or(vec![], |(_color, ranges)| {
ranges.iter().cloned().collect::<Vec<_>>()
.map_or(vec![], |highlight| {
highlight.ranges().iter().cloned().collect::<Vec<_>>()
});
cx.background_spawn(async move {

View File

@@ -576,7 +576,7 @@ impl EditorTestContext {
editor
.background_highlights
.get(&HighlightKey::Type(TypeId::of::<Tag>()))
.map(|h| h.1.clone())
.map(|h| h.ranges().to_vec())
.unwrap_or_default()
.iter()
.map(|range| range.to_offset(&snapshot.buffer_snapshot()))

View File

@@ -805,11 +805,13 @@ impl SearchableItem for LspLogView {
fn update_matches(
&mut self,
matches: &[Self::Match],
active_match_index: Option<usize>,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.editor
.update(cx, |e, cx| e.update_matches(matches, window, cx))
self.editor.update(cx, |e, cx| {
e.update_matches(matches, active_match_index, window, cx)
})
}
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {

View File

@@ -1,5 +1,8 @@
use command_palette_hooks::CommandPaletteFilter;
use editor::{Anchor, Editor, ExcerptId, MultiBufferOffset, SelectionEffects, scroll::Autoscroll};
use editor::{
Anchor, Editor, ExcerptId, MultiBufferOffset, SelectionEffects, BackgroundHighlight,
scroll::Autoscroll,
};
use gpui::{
App, AppContext as _, Context, Div, Entity, EntityId, EventEmitter, FocusHandle, Focusable,
Hsla, InteractiveElement, IntoElement, MouseButton, MouseDownEvent, MouseMoveEvent,
@@ -457,13 +460,12 @@ impl SyntaxTreeView {
cx,
|editor, range, _, cx| {
editor.clear_background_highlights::<Self>(cx);
editor.highlight_background::<Self>(
&[range],
|theme| {
editor.highlight_background::<Self, _>(
BackgroundHighlight::new(&[range], |theme| {
theme
.colors()
.editor_document_highlight_write_background
},
}),
cx,
);
},

View File

@@ -1031,7 +1031,7 @@ impl BufferSearchBar {
let new_match_index = searchable_item
.match_index_for_direction(matches, index, direction, count, window, cx);
searchable_item.update_matches(matches, window, cx);
searchable_item.update_matches(matches, Some(new_match_index), window, cx);
searchable_item.activate_match(new_match_index, matches, window, cx);
}
}
@@ -1045,7 +1045,7 @@ impl BufferSearchBar {
if matches.is_empty() {
return;
}
searchable_item.update_matches(matches, window, cx);
searchable_item.update_matches(matches, Some(0), window, cx);
searchable_item.activate_match(0, matches, window, cx);
}
}
@@ -1060,7 +1060,7 @@ impl BufferSearchBar {
return;
}
let new_match_index = matches.len() - 1;
searchable_item.update_matches(matches, window, cx);
searchable_item.update_matches(matches, Some(new_match_index), window, cx);
searchable_item.activate_match(new_match_index, matches, window, cx);
}
}
@@ -1300,7 +1300,12 @@ impl BufferSearchBar {
if matches.is_empty() {
active_searchable_item.clear_matches(window, cx);
} else {
active_searchable_item.update_matches(matches, window, cx);
active_searchable_item.update_matches(
matches,
this.active_match_index,
window,
cx,
);
}
let _ = done_tx.send(());
}
@@ -1335,6 +1340,20 @@ impl BufferSearchBar {
});
if new_index != self.active_match_index {
self.active_match_index = new_index;
if !self.dismissed {
if let Some(searchable_item) = self.active_searchable_item.as_ref() {
if let Some(matches) = self
.searchable_items_with_matches
.get(&searchable_item.downgrade())
{
if !matches.is_empty() {
searchable_item.update_matches(matches, new_index, window, cx);
}
}
}
}
cx.notify();
}
}

View File

@@ -8,8 +8,8 @@ use crate::{
use anyhow::Context as _;
use collections::HashMap;
use editor::{
Anchor, Editor, EditorEvent, EditorSettings, MAX_TAB_TITLE_LEN, MultiBuffer, PathKey,
SelectionEffects,
ActiveBackgroundHighlight, Anchor, Editor, EditorEvent, EditorSettings, MAX_TAB_TITLE_LEN,
MultiBuffer, PathKey, SelectionEffects,
actions::{Backtab, SelectAll, Tab},
items::active_match_index,
multibuffer_context_lines,
@@ -1443,6 +1443,10 @@ impl ProjectSearchView {
editor.change_selections(SelectionEffects::scroll(autoscroll), window, cx, |s| {
s.select_ranges([range_to_select])
});
editor.highlight_background::<Self, _>(
ActiveBackgroundHighlight::new(&match_ranges, Some(new_index)),
cx,
);
});
}
}
@@ -1518,11 +1522,6 @@ impl ProjectSearchView {
});
editor.scroll(Point::default(), Some(Axis::Vertical), window, cx);
}
editor.highlight_background::<Self>(
&match_ranges,
|theme| theme.colors().search_match_background,
cx,
);
});
if is_new_search && self.query_editor.focus_handle(cx).is_focused(window) {
self.focus_results_editor(window, cx);
@@ -1541,6 +1540,12 @@ impl ProjectSearchView {
&results_editor.selections.newest_anchor().head(),
&results_editor.buffer().read(cx).snapshot(cx),
);
self.results_editor.update(cx, |editor, cx| {
editor.highlight_background::<Self, _>(
ActiveBackgroundHighlight::new(&self.entity.read(cx).match_ranges, new_index),
cx,
);
});
if self.active_match_index != new_index {
self.active_match_index = new_index;
cx.notify();
@@ -2494,6 +2499,7 @@ pub mod tests {
"\n\nconst THREE: usize = one::ONE + two::TWO;\n\n\nconst TWO: usize = one::ONE + one::ONE;"
);
let match_background_color = cx.theme().colors().search_match_background;
// let active_match_background_color = cx.theme().colors().search_active_match_background;
let selection_background_color = cx.theme().colors().editor_document_highlight_bracket_background;
assert_eq!(
search_view
@@ -2515,6 +2521,7 @@ pub mod tests {
(
DisplayPoint::new(DisplayRow(5), 6)..DisplayPoint::new(DisplayRow(5), 9),
match_background_color
// active_match_background_color
),
]

View File

@@ -570,6 +570,9 @@ pub struct ThemeColorsContent {
#[serde(rename = "search.match_background")]
pub search_match_background: Option<String>,
#[serde(rename = "search.active_match_background")]
pub search_active_match_background: Option<String>,
#[serde(rename = "panel.background")]
pub panel_background: Option<String>,

View File

@@ -1434,6 +1434,7 @@ impl SearchableItem for TerminalView {
fn update_matches(
&mut self,
matches: &[Self::Match],
_active_match_index: Option<usize>,
_window: &mut Window,
cx: &mut Context<Self>,
) {

View File

@@ -91,6 +91,7 @@ impl ThemeColors {
tab_inactive_background: neutral().light().step_2(),
tab_active_background: neutral().light().step_1(),
search_match_background: neutral().light().step_5(),
search_active_match_background: neutral().light().step_7(),
panel_background: neutral().light().step_2(),
panel_focused_border: blue().light().step_10(),
panel_indent_guide: neutral().light_alpha().step_5(),
@@ -228,6 +229,7 @@ impl ThemeColors {
tab_inactive_background: neutral().dark().step_2(),
tab_active_background: neutral().dark().step_1(),
search_match_background: neutral().dark().step_5(),
search_active_match_background: neutral().dark().step_3(),
panel_background: neutral().dark().step_2(),
panel_focused_border: blue().dark().step_8(),
panel_indent_guide: neutral().dark_alpha().step_4(),

View File

@@ -152,6 +152,7 @@ pub(crate) fn zed_default_dark() -> Theme {
tab_inactive_background: bg,
tab_active_background: editor,
search_match_background: bg,
search_active_match_background: bg,
editor_background: editor,
editor_gutter_background: editor,

View File

@@ -287,6 +287,15 @@ pub fn theme_colors_refinement(
.panel_background
.as_ref()
.and_then(|color| try_parse_color(color).ok());
let search_match_background = this
.search_match_background
.as_ref()
.and_then(|color| try_parse_color(color).ok());
let search_active_match_background = this
.search_active_match_background
.as_ref()
.and_then(|color| try_parse_color(color).ok())
.or(search_match_background);
ThemeColorsRefinement {
border,
border_variant: this
@@ -442,10 +451,8 @@ pub fn theme_colors_refinement(
.tab_active_background
.as_ref()
.and_then(|color| try_parse_color(color).ok()),
search_match_background: this
.search_match_background
.as_ref()
.and_then(|color| try_parse_color(color).ok()),
search_match_background: search_match_background,
search_active_match_background: search_active_match_background,
panel_background,
panel_focused_border: this
.panel_focused_border

View File

@@ -128,6 +128,7 @@ pub struct ThemeColors {
pub tab_inactive_background: Hsla,
pub tab_active_background: Hsla,
pub search_match_background: Hsla,
pub search_active_match_background: Hsla,
pub panel_background: Hsla,
pub panel_focused_border: Hsla,
pub panel_indent_guide: Hsla,
@@ -352,6 +353,7 @@ pub enum ThemeColorField {
TabInactiveBackground,
TabActiveBackground,
SearchMatchBackground,
SearchActiveMatchBackground,
PanelBackground,
PanelFocusedBorder,
PanelIndentGuide,
@@ -467,6 +469,7 @@ impl ThemeColors {
ThemeColorField::TabInactiveBackground => self.tab_inactive_background,
ThemeColorField::TabActiveBackground => self.tab_active_background,
ThemeColorField::SearchMatchBackground => self.search_match_background,
ThemeColorField::SearchActiveMatchBackground => self.search_active_match_background,
ThemeColorField::PanelBackground => self.panel_background,
ThemeColorField::PanelFocusedBorder => self.panel_focused_border,
ThemeColorField::PanelIndentGuide => self.panel_indent_guide,

View File

@@ -7,7 +7,7 @@ use crate::{
state::{Mode, Register},
};
use collections::HashMap;
use editor::{ClipboardSelection, Editor, SelectionEffects};
use editor::{ClipboardSelection, Editor, SelectionEffects, BackgroundHighlight};
use gpui::Context;
use gpui::Window;
use language::Point;
@@ -221,9 +221,10 @@ impl Vim {
return;
}
editor.highlight_background::<HighlightOnYank>(
&ranges_to_highlight,
|colors| colors.colors().editor_document_highlight_read_background,
editor.highlight_background::<HighlightOnYank, _>(
BackgroundHighlight::new(&ranges_to_highlight, |colors| {
colors.colors().editor_document_highlight_read_background
}),
cx,
);
cx.spawn(async move |this, cx| {

View File

@@ -5,8 +5,8 @@ use crate::{
state::Mode,
};
use editor::{
Anchor, Bias, Editor, EditorSnapshot, SelectionEffects, ToOffset, ToPoint,
display_map::ToDisplayPoint,
Anchor, Bias, Editor, EditorSnapshot, SelectionEffects, BackgroundHighlight, ToOffset,
ToPoint, display_map::ToDisplayPoint,
};
use gpui::{ClipboardEntry, Context, Window, actions};
use language::{Point, SelectionGoal};
@@ -229,8 +229,8 @@ impl Vim {
window: &mut Window,
cx: &mut Context<Editor>,
) {
if let Some((_, ranges)) = editor.clear_background_highlights::<VimExchange>(cx) {
let previous_range = ranges[0].clone();
if let Some(highlight) = editor.clear_background_highlights::<VimExchange>(cx) {
let previous_range = highlight.ranges()[0].clone();
let new_range_start = new_range.start.to_offset(&snapshot.buffer_snapshot());
let new_range_end = new_range.end.to_offset(&snapshot.buffer_snapshot());
@@ -271,9 +271,10 @@ impl Vim {
}
} else {
let ranges = [new_range];
editor.highlight_background::<VimExchange>(
&ranges,
|theme| theme.colors().editor_document_highlight_read_background,
editor.highlight_background::<VimExchange, _>(
BackgroundHighlight::new(&ranges, |theme| {
theme.colors().editor_document_highlight_read_background
}),
cx,
);
}

View File

@@ -96,6 +96,7 @@ pub trait SearchableItem: Item + EventEmitter<SearchEvent> {
fn update_matches(
&mut self,
matches: &[Self::Match],
active_match_index: Option<usize>,
window: &mut Window,
cx: &mut Context<Self>,
);
@@ -179,7 +180,13 @@ pub trait SearchableItemHandle: ItemHandle {
handler: Box<dyn Fn(&SearchEvent, &mut Window, &mut App) + Send>,
) -> Subscription;
fn clear_matches(&self, window: &mut Window, cx: &mut App);
fn update_matches(&self, matches: &AnyVec<dyn Send>, window: &mut Window, cx: &mut App);
fn update_matches(
&self,
matches: &AnyVec<dyn Send>,
active_match_index: Option<usize>,
window: &mut Window,
cx: &mut App,
);
fn query_suggestion(&self, window: &mut Window, cx: &mut App) -> String;
fn activate_match(
&self,
@@ -264,10 +271,16 @@ impl<T: SearchableItem> SearchableItemHandle for Entity<T> {
fn clear_matches(&self, window: &mut Window, cx: &mut App) {
self.update(cx, |this, cx| this.clear_matches(window, cx));
}
fn update_matches(&self, matches: &AnyVec<dyn Send>, window: &mut Window, cx: &mut App) {
fn update_matches(
&self,
matches: &AnyVec<dyn Send>,
active_match_index: Option<usize>,
window: &mut Window,
cx: &mut App,
) {
let matches = matches.downcast_ref().unwrap();
self.update(cx, |this, cx| {
this.update_matches(matches.as_slice(), window, cx)
this.update_matches(matches.as_slice(), active_match_index, window, cx)
});
}
fn query_suggestion(&self, window: &mut Window, cx: &mut App) -> String {