editor: Add active match highlight for buffer and project search (#44098)
Closes #28617 <img width="400" alt="image" src="https://github.com/user-attachments/assets/b1c2880c-5744-4bed-a687-5c5e7aa7fef5" /> Release Notes: - Improved visibility of the currently active match when browsing results in buffer or project search. --------- Co-authored-by: DarkMatter-999 <darkmatter999official@gmail.com>
This commit is contained in:
@@ -45,6 +45,7 @@
|
|||||||
"tab.inactive_background": "#1f2127ff",
|
"tab.inactive_background": "#1f2127ff",
|
||||||
"tab.active_background": "#0d1016ff",
|
"tab.active_background": "#0d1016ff",
|
||||||
"search.match_background": "#5ac2fe66",
|
"search.match_background": "#5ac2fe66",
|
||||||
|
"search.active_match_background": "#ea570166",
|
||||||
"panel.background": "#1f2127ff",
|
"panel.background": "#1f2127ff",
|
||||||
"panel.focused_border": "#5ac1feff",
|
"panel.focused_border": "#5ac1feff",
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
@@ -436,6 +437,7 @@
|
|||||||
"tab.inactive_background": "#ececedff",
|
"tab.inactive_background": "#ececedff",
|
||||||
"tab.active_background": "#fcfcfcff",
|
"tab.active_background": "#fcfcfcff",
|
||||||
"search.match_background": "#3b9ee566",
|
"search.match_background": "#3b9ee566",
|
||||||
|
"search.active_match_background": "#f88b3666",
|
||||||
"panel.background": "#ececedff",
|
"panel.background": "#ececedff",
|
||||||
"panel.focused_border": "#3b9ee5ff",
|
"panel.focused_border": "#3b9ee5ff",
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
@@ -827,6 +829,7 @@
|
|||||||
"tab.inactive_background": "#353944ff",
|
"tab.inactive_background": "#353944ff",
|
||||||
"tab.active_background": "#242835ff",
|
"tab.active_background": "#242835ff",
|
||||||
"search.match_background": "#73cffe66",
|
"search.match_background": "#73cffe66",
|
||||||
|
"search.active_match_background": "#fd722b66",
|
||||||
"panel.background": "#353944ff",
|
"panel.background": "#353944ff",
|
||||||
"panel.focused_border": null,
|
"panel.focused_border": null,
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
"tab.inactive_background": "#3a3735ff",
|
"tab.inactive_background": "#3a3735ff",
|
||||||
"tab.active_background": "#282828ff",
|
"tab.active_background": "#282828ff",
|
||||||
"search.match_background": "#83a59866",
|
"search.match_background": "#83a59866",
|
||||||
|
"search.active_match_background": "#c09f3f66",
|
||||||
"panel.background": "#3a3735ff",
|
"panel.background": "#3a3735ff",
|
||||||
"panel.focused_border": "#83a598ff",
|
"panel.focused_border": "#83a598ff",
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
@@ -452,6 +453,7 @@
|
|||||||
"tab.inactive_background": "#393634ff",
|
"tab.inactive_background": "#393634ff",
|
||||||
"tab.active_background": "#1d2021ff",
|
"tab.active_background": "#1d2021ff",
|
||||||
"search.match_background": "#83a59866",
|
"search.match_background": "#83a59866",
|
||||||
|
"search.active_match_background": "#c9653666",
|
||||||
"panel.background": "#393634ff",
|
"panel.background": "#393634ff",
|
||||||
"panel.focused_border": "#83a598ff",
|
"panel.focused_border": "#83a598ff",
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
@@ -858,6 +860,7 @@
|
|||||||
"tab.inactive_background": "#3b3735ff",
|
"tab.inactive_background": "#3b3735ff",
|
||||||
"tab.active_background": "#32302fff",
|
"tab.active_background": "#32302fff",
|
||||||
"search.match_background": "#83a59866",
|
"search.match_background": "#83a59866",
|
||||||
|
"search.active_match_background": "#aea85166",
|
||||||
"panel.background": "#3b3735ff",
|
"panel.background": "#3b3735ff",
|
||||||
"panel.focused_border": null,
|
"panel.focused_border": null,
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
@@ -1264,6 +1267,7 @@
|
|||||||
"tab.inactive_background": "#ecddb4ff",
|
"tab.inactive_background": "#ecddb4ff",
|
||||||
"tab.active_background": "#fbf1c7ff",
|
"tab.active_background": "#fbf1c7ff",
|
||||||
"search.match_background": "#0b667866",
|
"search.match_background": "#0b667866",
|
||||||
|
"search.active_match_background": "#ba2d1166",
|
||||||
"panel.background": "#ecddb4ff",
|
"panel.background": "#ecddb4ff",
|
||||||
"panel.focused_border": null,
|
"panel.focused_border": null,
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
@@ -1670,6 +1674,7 @@
|
|||||||
"tab.inactive_background": "#ecddb5ff",
|
"tab.inactive_background": "#ecddb5ff",
|
||||||
"tab.active_background": "#f9f5d7ff",
|
"tab.active_background": "#f9f5d7ff",
|
||||||
"search.match_background": "#0b667866",
|
"search.match_background": "#0b667866",
|
||||||
|
"search.active_match_background": "#dc351466",
|
||||||
"panel.background": "#ecddb5ff",
|
"panel.background": "#ecddb5ff",
|
||||||
"panel.focused_border": null,
|
"panel.focused_border": null,
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
@@ -2076,6 +2081,7 @@
|
|||||||
"tab.inactive_background": "#ecdcb3ff",
|
"tab.inactive_background": "#ecdcb3ff",
|
||||||
"tab.active_background": "#f2e5bcff",
|
"tab.active_background": "#f2e5bcff",
|
||||||
"search.match_background": "#0b667866",
|
"search.match_background": "#0b667866",
|
||||||
|
"search.active_match_background": "#d7331466",
|
||||||
"panel.background": "#ecdcb3ff",
|
"panel.background": "#ecdcb3ff",
|
||||||
"panel.focused_border": null,
|
"panel.focused_border": null,
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
"tab.inactive_background": "#2f343eff",
|
"tab.inactive_background": "#2f343eff",
|
||||||
"tab.active_background": "#282c33ff",
|
"tab.active_background": "#282c33ff",
|
||||||
"search.match_background": "#74ade866",
|
"search.match_background": "#74ade866",
|
||||||
|
"search.active_match_background": "#e8af7466",
|
||||||
"panel.background": "#2f343eff",
|
"panel.background": "#2f343eff",
|
||||||
"panel.focused_border": null,
|
"panel.focused_border": null,
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
@@ -448,6 +449,7 @@
|
|||||||
"tab.inactive_background": "#ebebecff",
|
"tab.inactive_background": "#ebebecff",
|
||||||
"tab.active_background": "#fafafaff",
|
"tab.active_background": "#fafafaff",
|
||||||
"search.match_background": "#5c79e266",
|
"search.match_background": "#5c79e266",
|
||||||
|
"search.active_match_background": "#d0a92366",
|
||||||
"panel.background": "#ebebecff",
|
"panel.background": "#ebebecff",
|
||||||
"panel.focused_border": null,
|
"panel.focused_border": null,
|
||||||
"pane.focused_border": null,
|
"pane.focused_border": null,
|
||||||
|
|||||||
@@ -2622,11 +2622,13 @@ impl SearchableItem for TextThreadEditor {
|
|||||||
fn update_matches(
|
fn update_matches(
|
||||||
&mut self,
|
&mut self,
|
||||||
matches: &[Self::Match],
|
matches: &[Self::Match],
|
||||||
|
active_match_index: Option<usize>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
self.editor
|
self.editor.update(cx, |editor, cx| {
|
||||||
.update(cx, |editor, cx| editor.update_matches(matches, window, cx));
|
editor.update_matches(matches, active_match_index, window, cx)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
|
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
|
||||||
|
|||||||
@@ -1017,11 +1017,13 @@ impl SearchableItem for DapLogView {
|
|||||||
fn update_matches(
|
fn update_matches(
|
||||||
&mut self,
|
&mut self,
|
||||||
matches: &[Self::Match],
|
matches: &[Self::Match],
|
||||||
|
active_match_index: Option<usize>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
self.editor
|
self.editor.update(cx, |e, cx| {
|
||||||
.update(cx, |e, cx| e.update_matches(matches, window, cx))
|
e.update_matches(matches, active_match_index, window, cx)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
|
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
|
||||||
|
|||||||
@@ -252,10 +252,11 @@ impl Console {
|
|||||||
let start_offset = range.start;
|
let start_offset = range.start;
|
||||||
let range = buffer.anchor_after(MultiBufferOffset(range.start))
|
let range = buffer.anchor_after(MultiBufferOffset(range.start))
|
||||||
..buffer.anchor_before(MultiBufferOffset(range.end));
|
..buffer.anchor_before(MultiBufferOffset(range.end));
|
||||||
|
let color_fn = color_fetcher(color);
|
||||||
console.highlight_background_key::<ConsoleAnsiHighlight>(
|
console.highlight_background_key::<ConsoleAnsiHighlight>(
|
||||||
start_offset,
|
start_offset,
|
||||||
&[range],
|
&[range],
|
||||||
color_fetcher(color),
|
move |_, theme| color_fn(theme),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -726,7 +726,10 @@ impl EditorActionId {
|
|||||||
// type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor;
|
// type GetFieldEditorTheme = dyn Fn(&theme::Theme) -> theme::FieldEditor;
|
||||||
// type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>;
|
// type OverrideTextStyle = dyn Fn(&EditorStyle) -> Option<HighlightStyle>;
|
||||||
|
|
||||||
type BackgroundHighlight = (fn(&Theme) -> Hsla, Arc<[Range<Anchor>]>);
|
type BackgroundHighlight = (
|
||||||
|
Arc<dyn Fn(&usize, &Theme) -> Hsla + Send + Sync>,
|
||||||
|
Arc<[Range<Anchor>]>,
|
||||||
|
);
|
||||||
type GutterHighlight = (fn(&App) -> Hsla, Vec<Range<Anchor>>);
|
type GutterHighlight = (fn(&App) -> Hsla, Vec<Range<Anchor>>);
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@@ -6610,7 +6613,7 @@ impl Editor {
|
|||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
editor.highlight_background::<Self>(
|
editor.highlight_background::<Self>(
|
||||||
&ranges_to_highlight,
|
&ranges_to_highlight,
|
||||||
|theme| theme.colors().editor_highlighted_line_background,
|
|_, theme| theme.colors().editor_highlighted_line_background,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -7012,12 +7015,12 @@ impl Editor {
|
|||||||
|
|
||||||
this.highlight_background::<DocumentHighlightRead>(
|
this.highlight_background::<DocumentHighlightRead>(
|
||||||
&read_ranges,
|
&read_ranges,
|
||||||
|theme| theme.colors().editor_document_highlight_read_background,
|
|_, theme| theme.colors().editor_document_highlight_read_background,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
this.highlight_background::<DocumentHighlightWrite>(
|
this.highlight_background::<DocumentHighlightWrite>(
|
||||||
&write_ranges,
|
&write_ranges,
|
||||||
|theme| theme.colors().editor_document_highlight_write_background,
|
|_, theme| theme.colors().editor_document_highlight_write_background,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@@ -7125,7 +7128,7 @@ impl Editor {
|
|||||||
if !match_ranges.is_empty() {
|
if !match_ranges.is_empty() {
|
||||||
editor.highlight_background::<SelectedTextHighlight>(
|
editor.highlight_background::<SelectedTextHighlight>(
|
||||||
&match_ranges,
|
&match_ranges,
|
||||||
|theme| theme.colors().editor_document_highlight_bracket_background,
|
|_, theme| theme.colors().editor_document_highlight_bracket_background,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -17519,7 +17522,7 @@ impl Editor {
|
|||||||
}
|
}
|
||||||
editor.highlight_background::<Self>(
|
editor.highlight_background::<Self>(
|
||||||
&ranges,
|
&ranges,
|
||||||
|theme| theme.colors().editor_highlighted_line_background,
|
|_, theme| theme.colors().editor_highlighted_line_background,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -20989,7 +20992,7 @@ impl Editor {
|
|||||||
pub fn set_search_within_ranges(&mut self, ranges: &[Range<Anchor>], cx: &mut Context<Self>) {
|
pub fn set_search_within_ranges(&mut self, ranges: &[Range<Anchor>], cx: &mut Context<Self>) {
|
||||||
self.highlight_background::<SearchWithinRange>(
|
self.highlight_background::<SearchWithinRange>(
|
||||||
ranges,
|
ranges,
|
||||||
|colors| colors.colors().editor_document_highlight_read_background,
|
|_, colors| colors.colors().editor_document_highlight_read_background,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -21005,12 +21008,12 @@ impl Editor {
|
|||||||
pub fn highlight_background<T: 'static>(
|
pub fn highlight_background<T: 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ranges: &[Range<Anchor>],
|
ranges: &[Range<Anchor>],
|
||||||
color_fetcher: fn(&Theme) -> Hsla,
|
color_fetcher: impl Fn(&usize, &Theme) -> Hsla + Send + Sync + 'static,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
self.background_highlights.insert(
|
self.background_highlights.insert(
|
||||||
HighlightKey::Type(TypeId::of::<T>()),
|
HighlightKey::Type(TypeId::of::<T>()),
|
||||||
(color_fetcher, Arc::from(ranges)),
|
(Arc::new(color_fetcher), Arc::from(ranges)),
|
||||||
);
|
);
|
||||||
self.scrollbar_marker_state.dirty = true;
|
self.scrollbar_marker_state.dirty = true;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@@ -21020,12 +21023,12 @@ impl Editor {
|
|||||||
&mut self,
|
&mut self,
|
||||||
key: usize,
|
key: usize,
|
||||||
ranges: &[Range<Anchor>],
|
ranges: &[Range<Anchor>],
|
||||||
color_fetcher: fn(&Theme) -> Hsla,
|
color_fetcher: impl Fn(&usize, &Theme) -> Hsla + Send + Sync + 'static,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
self.background_highlights.insert(
|
self.background_highlights.insert(
|
||||||
HighlightKey::TypePlus(TypeId::of::<T>(), key),
|
HighlightKey::TypePlus(TypeId::of::<T>(), key),
|
||||||
(color_fetcher, Arc::from(ranges)),
|
(Arc::new(color_fetcher), Arc::from(ranges)),
|
||||||
);
|
);
|
||||||
self.scrollbar_marker_state.dirty = true;
|
self.scrollbar_marker_state.dirty = true;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@@ -21250,7 +21253,6 @@ impl Editor {
|
|||||||
) -> Vec<(Range<DisplayPoint>, Hsla)> {
|
) -> Vec<(Range<DisplayPoint>, Hsla)> {
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
for (color_fetcher, ranges) in self.background_highlights.values() {
|
for (color_fetcher, ranges) in self.background_highlights.values() {
|
||||||
let color = color_fetcher(theme);
|
|
||||||
let start_ix = match ranges.binary_search_by(|probe| {
|
let start_ix = match ranges.binary_search_by(|probe| {
|
||||||
let cmp = probe
|
let cmp = probe
|
||||||
.end
|
.end
|
||||||
@@ -21263,7 +21265,7 @@ impl Editor {
|
|||||||
}) {
|
}) {
|
||||||
Ok(i) | Err(i) => i,
|
Ok(i) | Err(i) => i,
|
||||||
};
|
};
|
||||||
for range in &ranges[start_ix..] {
|
for (index, range) in ranges[start_ix..].iter().enumerate() {
|
||||||
if range
|
if range
|
||||||
.start
|
.start
|
||||||
.cmp(&search_range.end, &display_snapshot.buffer_snapshot())
|
.cmp(&search_range.end, &display_snapshot.buffer_snapshot())
|
||||||
@@ -21272,6 +21274,7 @@ impl Editor {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let color = color_fetcher(&(start_ix + index), theme);
|
||||||
let start = range.start.to_display_point(display_snapshot);
|
let start = range.start.to_display_point(display_snapshot);
|
||||||
let end = range.end.to_display_point(display_snapshot);
|
let end = range.end.to_display_point(display_snapshot);
|
||||||
results.push((start..end, color))
|
results.push((start..end, color))
|
||||||
|
|||||||
@@ -16978,7 +16978,7 @@ fn test_highlighted_ranges(cx: &mut TestAppContext) {
|
|||||||
anchor_range(Point::new(6, 3)..Point::new(6, 5)),
|
anchor_range(Point::new(6, 3)..Point::new(6, 5)),
|
||||||
anchor_range(Point::new(8, 4)..Point::new(8, 6)),
|
anchor_range(Point::new(8, 4)..Point::new(8, 6)),
|
||||||
],
|
],
|
||||||
|_| Hsla::red(),
|
|_, _| Hsla::red(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
editor.highlight_background::<Type2>(
|
editor.highlight_background::<Type2>(
|
||||||
@@ -16988,7 +16988,7 @@ fn test_highlighted_ranges(cx: &mut TestAppContext) {
|
|||||||
anchor_range(Point::new(7, 4)..Point::new(7, 7)),
|
anchor_range(Point::new(7, 4)..Point::new(7, 7)),
|
||||||
anchor_range(Point::new(9, 5)..Point::new(9, 8)),
|
anchor_range(Point::new(9, 5)..Point::new(9, 8)),
|
||||||
],
|
],
|
||||||
|_| Hsla::green(),
|
|_, _| Hsla::green(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -23973,7 +23973,7 @@ async fn test_rename_with_duplicate_edits(cx: &mut TestAppContext) {
|
|||||||
let highlight_range = highlight_range.to_anchors(&editor.buffer().read(cx).snapshot(cx));
|
let highlight_range = highlight_range.to_anchors(&editor.buffer().read(cx).snapshot(cx));
|
||||||
editor.highlight_background::<DocumentHighlightRead>(
|
editor.highlight_background::<DocumentHighlightRead>(
|
||||||
&[highlight_range],
|
&[highlight_range],
|
||||||
|theme| theme.colors().editor_document_highlight_read_background,
|
|_, theme| theme.colors().editor_document_highlight_read_background,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -24051,7 +24051,7 @@ async fn test_rename_without_prepare(cx: &mut TestAppContext) {
|
|||||||
let highlight_range = highlight_range.to_anchors(&editor.buffer().read(cx).snapshot(cx));
|
let highlight_range = highlight_range.to_anchors(&editor.buffer().read(cx).snapshot(cx));
|
||||||
editor.highlight_background::<DocumentHighlightRead>(
|
editor.highlight_background::<DocumentHighlightRead>(
|
||||||
&[highlight_range],
|
&[highlight_range],
|
||||||
|theme| theme.colors().editor_document_highlight_read_background,
|
|_, theme| theme.colors().editor_document_highlight_read_background,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -27299,7 +27299,7 @@ let result = variable * 2;",
|
|||||||
|
|
||||||
editor.highlight_background::<DocumentHighlightRead>(
|
editor.highlight_background::<DocumentHighlightRead>(
|
||||||
&anchor_ranges,
|
&anchor_ranges,
|
||||||
|theme| theme.colors().editor_document_highlight_read_background,
|
|_, theme| theme.colors().editor_document_highlight_read_background,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -518,7 +518,7 @@ fn show_hover(
|
|||||||
// Highlight the selected symbol using a background highlight
|
// Highlight the selected symbol using a background highlight
|
||||||
editor.highlight_background::<HoverState>(
|
editor.highlight_background::<HoverState>(
|
||||||
&hover_highlights,
|
&hover_highlights,
|
||||||
|theme| theme.colors().element_hover, // todo update theme
|
|_, theme| theme.colors().element_hover, // todo update theme
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1487,6 +1487,7 @@ impl SearchableItem for Editor {
|
|||||||
fn update_matches(
|
fn update_matches(
|
||||||
&mut self,
|
&mut self,
|
||||||
matches: &[Range<Anchor>],
|
matches: &[Range<Anchor>],
|
||||||
|
active_match_index: Option<usize>,
|
||||||
_: &mut Window,
|
_: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
@@ -1497,7 +1498,13 @@ impl SearchableItem for Editor {
|
|||||||
let updated = existing_range != Some(matches);
|
let updated = existing_range != Some(matches);
|
||||||
self.highlight_background::<BufferSearchHighlights>(
|
self.highlight_background::<BufferSearchHighlights>(
|
||||||
matches,
|
matches,
|
||||||
|theme| theme.colors().search_match_background,
|
move |index, theme| {
|
||||||
|
if active_match_index == Some(*index) {
|
||||||
|
theme.colors().search_active_match_background
|
||||||
|
} else {
|
||||||
|
theme.colors().search_match_background
|
||||||
|
}
|
||||||
|
},
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
if updated {
|
if updated {
|
||||||
|
|||||||
@@ -805,11 +805,13 @@ impl SearchableItem for LspLogView {
|
|||||||
fn update_matches(
|
fn update_matches(
|
||||||
&mut self,
|
&mut self,
|
||||||
matches: &[Self::Match],
|
matches: &[Self::Match],
|
||||||
|
active_match_index: Option<usize>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
self.editor
|
self.editor.update(cx, |e, cx| {
|
||||||
.update(cx, |e, cx| e.update_matches(matches, window, cx))
|
e.update_matches(matches, active_match_index, window, cx)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
|
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ impl SyntaxTreeView {
|
|||||||
editor.clear_background_highlights::<Self>(cx);
|
editor.clear_background_highlights::<Self>(cx);
|
||||||
editor.highlight_background::<Self>(
|
editor.highlight_background::<Self>(
|
||||||
&[range],
|
&[range],
|
||||||
|theme| {
|
|_, theme| {
|
||||||
theme
|
theme
|
||||||
.colors()
|
.colors()
|
||||||
.editor_document_highlight_write_background
|
.editor_document_highlight_write_background
|
||||||
|
|||||||
@@ -1031,7 +1031,7 @@ impl BufferSearchBar {
|
|||||||
let new_match_index = searchable_item
|
let new_match_index = searchable_item
|
||||||
.match_index_for_direction(matches, index, direction, count, window, cx);
|
.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);
|
searchable_item.activate_match(new_match_index, matches, window, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1045,7 +1045,7 @@ impl BufferSearchBar {
|
|||||||
if matches.is_empty() {
|
if matches.is_empty() {
|
||||||
return;
|
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);
|
searchable_item.activate_match(0, matches, window, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1060,7 +1060,7 @@ impl BufferSearchBar {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let new_match_index = matches.len() - 1;
|
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);
|
searchable_item.activate_match(new_match_index, matches, window, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1300,7 +1300,12 @@ impl BufferSearchBar {
|
|||||||
if matches.is_empty() {
|
if matches.is_empty() {
|
||||||
active_searchable_item.clear_matches(window, cx);
|
active_searchable_item.clear_matches(window, cx);
|
||||||
} else {
|
} 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(());
|
let _ = done_tx.send(());
|
||||||
}
|
}
|
||||||
@@ -1335,6 +1340,18 @@ impl BufferSearchBar {
|
|||||||
});
|
});
|
||||||
if new_index != self.active_match_index {
|
if new_index != self.active_match_index {
|
||||||
self.active_match_index = new_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();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1444,6 +1444,7 @@ impl ProjectSearchView {
|
|||||||
s.select_ranges([range_to_select])
|
s.select_ranges([range_to_select])
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
self.highlight_matches(&match_ranges, Some(new_index), cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1518,11 +1519,6 @@ impl ProjectSearchView {
|
|||||||
});
|
});
|
||||||
editor.scroll(Point::default(), Some(Axis::Vertical), window, cx);
|
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) {
|
if is_new_search && self.query_editor.focus_handle(cx).is_focused(window) {
|
||||||
self.focus_results_editor(window, cx);
|
self.focus_results_editor(window, cx);
|
||||||
@@ -1535,18 +1531,41 @@ impl ProjectSearchView {
|
|||||||
|
|
||||||
fn update_match_index(&mut self, cx: &mut Context<Self>) {
|
fn update_match_index(&mut self, cx: &mut Context<Self>) {
|
||||||
let results_editor = self.results_editor.read(cx);
|
let results_editor = self.results_editor.read(cx);
|
||||||
|
let match_ranges = self.entity.read(cx).match_ranges.clone();
|
||||||
let new_index = active_match_index(
|
let new_index = active_match_index(
|
||||||
Direction::Next,
|
Direction::Next,
|
||||||
&self.entity.read(cx).match_ranges,
|
&match_ranges,
|
||||||
&results_editor.selections.newest_anchor().head(),
|
&results_editor.selections.newest_anchor().head(),
|
||||||
&results_editor.buffer().read(cx).snapshot(cx),
|
&results_editor.buffer().read(cx).snapshot(cx),
|
||||||
);
|
);
|
||||||
|
self.highlight_matches(&match_ranges, new_index, cx);
|
||||||
if self.active_match_index != new_index {
|
if self.active_match_index != new_index {
|
||||||
self.active_match_index = new_index;
|
self.active_match_index = new_index;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn highlight_matches(
|
||||||
|
&self,
|
||||||
|
match_ranges: &[Range<Anchor>],
|
||||||
|
active_index: Option<usize>,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
self.results_editor.update(cx, |editor, cx| {
|
||||||
|
editor.highlight_background::<Self>(
|
||||||
|
match_ranges,
|
||||||
|
move |index, theme| {
|
||||||
|
if active_index == Some(*index) {
|
||||||
|
theme.colors().search_active_match_background
|
||||||
|
} else {
|
||||||
|
theme.colors().search_match_background
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn has_matches(&self) -> bool {
|
pub fn has_matches(&self) -> bool {
|
||||||
self.active_match_index.is_some()
|
self.active_match_index.is_some()
|
||||||
}
|
}
|
||||||
@@ -2456,7 +2475,9 @@ pub mod tests {
|
|||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use project::FakeFs;
|
use project::FakeFs;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use settings::{InlayHintSettingsContent, SettingsStore};
|
use settings::{
|
||||||
|
InlayHintSettingsContent, SettingsStore, ThemeColorsContent, ThemeStyleContent,
|
||||||
|
};
|
||||||
use util::{path, paths::PathStyle, rel_path::rel_path};
|
use util::{path, paths::PathStyle, rel_path::rel_path};
|
||||||
use util_macros::perf;
|
use util_macros::perf;
|
||||||
use workspace::DeploySearch;
|
use workspace::DeploySearch;
|
||||||
@@ -2464,8 +2485,105 @@ pub mod tests {
|
|||||||
#[perf]
|
#[perf]
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_project_search(cx: &mut TestAppContext) {
|
async fn test_project_search(cx: &mut TestAppContext) {
|
||||||
|
fn dp(row: u32, col: u32) -> DisplayPoint {
|
||||||
|
DisplayPoint::new(DisplayRow(row), col)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_active_match_index(
|
||||||
|
search_view: &WindowHandle<ProjectSearchView>,
|
||||||
|
cx: &mut TestAppContext,
|
||||||
|
expected_index: usize,
|
||||||
|
) {
|
||||||
|
search_view
|
||||||
|
.update(cx, |search_view, _window, _cx| {
|
||||||
|
assert_eq!(search_view.active_match_index, Some(expected_index));
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_selection_range(
|
||||||
|
search_view: &WindowHandle<ProjectSearchView>,
|
||||||
|
cx: &mut TestAppContext,
|
||||||
|
expected_range: Range<DisplayPoint>,
|
||||||
|
) {
|
||||||
|
search_view
|
||||||
|
.update(cx, |search_view, _window, cx| {
|
||||||
|
assert_eq!(
|
||||||
|
search_view.results_editor.update(cx, |editor, cx| editor
|
||||||
|
.selections
|
||||||
|
.display_ranges(&editor.display_snapshot(cx))),
|
||||||
|
[expected_range]
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_highlights(
|
||||||
|
search_view: &WindowHandle<ProjectSearchView>,
|
||||||
|
cx: &mut TestAppContext,
|
||||||
|
expected_highlights: Vec<(Range<DisplayPoint>, &str)>,
|
||||||
|
) {
|
||||||
|
search_view
|
||||||
|
.update(cx, |search_view, window, cx| {
|
||||||
|
let match_bg = cx.theme().colors().search_match_background;
|
||||||
|
let active_match_bg = cx.theme().colors().search_active_match_background;
|
||||||
|
let selection_bg = cx
|
||||||
|
.theme()
|
||||||
|
.colors()
|
||||||
|
.editor_document_highlight_bracket_background;
|
||||||
|
|
||||||
|
let highlights: Vec<_> = expected_highlights
|
||||||
|
.into_iter()
|
||||||
|
.map(|(range, color_type)| {
|
||||||
|
let color = match color_type {
|
||||||
|
"active" => active_match_bg,
|
||||||
|
"match" => match_bg,
|
||||||
|
"selection" => selection_bg,
|
||||||
|
_ => panic!("Unknown color type"),
|
||||||
|
};
|
||||||
|
(range, color)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
search_view.results_editor.update(cx, |editor, cx| editor
|
||||||
|
.all_text_background_highlights(window, cx)),
|
||||||
|
highlights.as_slice()
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_match(
|
||||||
|
search_view: &WindowHandle<ProjectSearchView>,
|
||||||
|
cx: &mut TestAppContext,
|
||||||
|
direction: Direction,
|
||||||
|
) {
|
||||||
|
search_view
|
||||||
|
.update(cx, |search_view, window, cx| {
|
||||||
|
search_view.select_match(direction, window, cx);
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
init_test(cx);
|
init_test(cx);
|
||||||
|
|
||||||
|
// Override active search match color since the fallback theme uses the same color
|
||||||
|
// for normal search match and active one, which can make this test less robust.
|
||||||
|
cx.update(|cx| {
|
||||||
|
SettingsStore::update_global(cx, |settings, cx| {
|
||||||
|
settings.update_user_settings(cx, |settings| {
|
||||||
|
settings.theme.experimental_theme_overrides = Some(ThemeStyleContent {
|
||||||
|
colors: ThemeColorsContent {
|
||||||
|
search_active_match_background: Some("#ff0000ff".to_string()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
let fs = FakeFs::new(cx.background_executor.clone());
|
let fs = FakeFs::new(cx.background_executor.clone());
|
||||||
fs.insert_tree(
|
fs.insert_tree(
|
||||||
path!("/dir"),
|
path!("/dir"),
|
||||||
@@ -2486,113 +2604,113 @@ pub mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
perform_search(search_view, "TWO", cx);
|
perform_search(search_view, "TWO", cx);
|
||||||
search_view.update(cx, |search_view, window, cx| {
|
cx.run_until_parked();
|
||||||
assert_eq!(
|
|
||||||
search_view
|
|
||||||
.results_editor
|
|
||||||
.update(cx, |editor, cx| editor.display_text(cx)),
|
|
||||||
"\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 selection_background_color = cx.theme().colors().editor_document_highlight_bracket_background;
|
|
||||||
assert_eq!(
|
|
||||||
search_view
|
|
||||||
.results_editor
|
|
||||||
.update(cx, |editor, cx| editor.all_text_background_highlights(window, cx)),
|
|
||||||
&[
|
|
||||||
(
|
|
||||||
DisplayPoint::new(DisplayRow(2), 32)..DisplayPoint::new(DisplayRow(2), 35),
|
|
||||||
match_background_color
|
|
||||||
),
|
|
||||||
(
|
|
||||||
DisplayPoint::new(DisplayRow(2), 37)..DisplayPoint::new(DisplayRow(2), 40),
|
|
||||||
selection_background_color
|
|
||||||
),
|
|
||||||
(
|
|
||||||
DisplayPoint::new(DisplayRow(2), 37)..DisplayPoint::new(DisplayRow(2), 40),
|
|
||||||
match_background_color
|
|
||||||
),
|
|
||||||
(
|
|
||||||
DisplayPoint::new(DisplayRow(5), 6)..DisplayPoint::new(DisplayRow(5), 9),
|
|
||||||
match_background_color
|
|
||||||
),
|
|
||||||
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(search_view.active_match_index, Some(0));
|
|
||||||
assert_eq!(
|
|
||||||
search_view
|
|
||||||
.results_editor
|
|
||||||
.update(cx, |editor, cx| editor.selections.display_ranges(&editor.display_snapshot(cx))),
|
|
||||||
[DisplayPoint::new(DisplayRow(2), 32)..DisplayPoint::new(DisplayRow(2), 35)]
|
|
||||||
);
|
|
||||||
|
|
||||||
search_view.select_match(Direction::Next, window, cx);
|
|
||||||
}).unwrap();
|
|
||||||
|
|
||||||
search_view
|
search_view
|
||||||
.update(cx, |search_view, window, cx| {
|
.update(cx, |search_view, _window, cx| {
|
||||||
assert_eq!(search_view.active_match_index, Some(1));
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
search_view.results_editor.update(cx, |editor, cx| editor
|
search_view
|
||||||
.selections
|
.results_editor
|
||||||
.display_ranges(&editor.display_snapshot(cx))),
|
.update(cx, |editor, cx| editor.display_text(cx)),
|
||||||
[DisplayPoint::new(DisplayRow(2), 37)..DisplayPoint::new(DisplayRow(2), 40)]
|
"\n\nconst THREE: usize = one::ONE + two::TWO;\n\n\nconst TWO: usize = one::ONE + one::ONE;"
|
||||||
);
|
|
||||||
search_view.select_match(Direction::Next, window, cx);
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
search_view
|
|
||||||
.update(cx, |search_view, window, cx| {
|
|
||||||
assert_eq!(search_view.active_match_index, Some(2));
|
|
||||||
assert_eq!(
|
|
||||||
search_view.results_editor.update(cx, |editor, cx| editor
|
|
||||||
.selections
|
|
||||||
.display_ranges(&editor.display_snapshot(cx))),
|
|
||||||
[DisplayPoint::new(DisplayRow(5), 6)..DisplayPoint::new(DisplayRow(5), 9)]
|
|
||||||
);
|
|
||||||
search_view.select_match(Direction::Next, window, cx);
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
search_view
|
|
||||||
.update(cx, |search_view, window, cx| {
|
|
||||||
assert_eq!(search_view.active_match_index, Some(0));
|
|
||||||
assert_eq!(
|
|
||||||
search_view.results_editor.update(cx, |editor, cx| editor
|
|
||||||
.selections
|
|
||||||
.display_ranges(&editor.display_snapshot(cx))),
|
|
||||||
[DisplayPoint::new(DisplayRow(2), 32)..DisplayPoint::new(DisplayRow(2), 35)]
|
|
||||||
);
|
|
||||||
search_view.select_match(Direction::Prev, window, cx);
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
search_view
|
|
||||||
.update(cx, |search_view, window, cx| {
|
|
||||||
assert_eq!(search_view.active_match_index, Some(2));
|
|
||||||
assert_eq!(
|
|
||||||
search_view.results_editor.update(cx, |editor, cx| editor
|
|
||||||
.selections
|
|
||||||
.display_ranges(&editor.display_snapshot(cx))),
|
|
||||||
[DisplayPoint::new(DisplayRow(5), 6)..DisplayPoint::new(DisplayRow(5), 9)]
|
|
||||||
);
|
|
||||||
search_view.select_match(Direction::Prev, window, cx);
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
search_view
|
|
||||||
.update(cx, |search_view, _, cx| {
|
|
||||||
assert_eq!(search_view.active_match_index, Some(1));
|
|
||||||
assert_eq!(
|
|
||||||
search_view.results_editor.update(cx, |editor, cx| editor
|
|
||||||
.selections
|
|
||||||
.display_ranges(&editor.display_snapshot(cx))),
|
|
||||||
[DisplayPoint::new(DisplayRow(2), 37)..DisplayPoint::new(DisplayRow(2), 40)]
|
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
assert_active_match_index(&search_view, cx, 0);
|
||||||
|
assert_selection_range(&search_view, cx, dp(2, 32)..dp(2, 35));
|
||||||
|
assert_highlights(
|
||||||
|
&search_view,
|
||||||
|
cx,
|
||||||
|
vec![
|
||||||
|
(dp(2, 32)..dp(2, 35), "active"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "selection"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "match"),
|
||||||
|
(dp(5, 6)..dp(5, 9), "match"),
|
||||||
|
// TODO: we should be getting selection highlight here after project search
|
||||||
|
// but for some reason we are not getting it here
|
||||||
|
],
|
||||||
|
);
|
||||||
|
select_match(&search_view, cx, Direction::Next);
|
||||||
|
cx.run_until_parked();
|
||||||
|
|
||||||
|
assert_active_match_index(&search_view, cx, 1);
|
||||||
|
assert_selection_range(&search_view, cx, dp(2, 37)..dp(2, 40));
|
||||||
|
assert_highlights(
|
||||||
|
&search_view,
|
||||||
|
cx,
|
||||||
|
vec![
|
||||||
|
(dp(2, 32)..dp(2, 35), "selection"),
|
||||||
|
(dp(2, 32)..dp(2, 35), "match"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "active"),
|
||||||
|
(dp(5, 6)..dp(5, 9), "selection"),
|
||||||
|
(dp(5, 6)..dp(5, 9), "match"),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
select_match(&search_view, cx, Direction::Next);
|
||||||
|
cx.run_until_parked();
|
||||||
|
|
||||||
|
assert_active_match_index(&search_view, cx, 2);
|
||||||
|
assert_selection_range(&search_view, cx, dp(5, 6)..dp(5, 9));
|
||||||
|
assert_highlights(
|
||||||
|
&search_view,
|
||||||
|
cx,
|
||||||
|
vec![
|
||||||
|
(dp(2, 32)..dp(2, 35), "selection"),
|
||||||
|
(dp(2, 32)..dp(2, 35), "match"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "selection"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "match"),
|
||||||
|
(dp(5, 6)..dp(5, 9), "active"),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
select_match(&search_view, cx, Direction::Next);
|
||||||
|
cx.run_until_parked();
|
||||||
|
|
||||||
|
assert_active_match_index(&search_view, cx, 0);
|
||||||
|
assert_selection_range(&search_view, cx, dp(2, 32)..dp(2, 35));
|
||||||
|
assert_highlights(
|
||||||
|
&search_view,
|
||||||
|
cx,
|
||||||
|
vec![
|
||||||
|
(dp(2, 32)..dp(2, 35), "active"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "selection"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "match"),
|
||||||
|
(dp(5, 6)..dp(5, 9), "selection"),
|
||||||
|
(dp(5, 6)..dp(5, 9), "match"),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
select_match(&search_view, cx, Direction::Prev);
|
||||||
|
cx.run_until_parked();
|
||||||
|
|
||||||
|
assert_active_match_index(&search_view, cx, 2);
|
||||||
|
assert_selection_range(&search_view, cx, dp(5, 6)..dp(5, 9));
|
||||||
|
assert_highlights(
|
||||||
|
&search_view,
|
||||||
|
cx,
|
||||||
|
vec![
|
||||||
|
(dp(2, 32)..dp(2, 35), "selection"),
|
||||||
|
(dp(2, 32)..dp(2, 35), "match"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "selection"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "match"),
|
||||||
|
(dp(5, 6)..dp(5, 9), "active"),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
select_match(&search_view, cx, Direction::Prev);
|
||||||
|
cx.run_until_parked();
|
||||||
|
|
||||||
|
assert_active_match_index(&search_view, cx, 1);
|
||||||
|
assert_selection_range(&search_view, cx, dp(2, 37)..dp(2, 40));
|
||||||
|
assert_highlights(
|
||||||
|
&search_view,
|
||||||
|
cx,
|
||||||
|
vec![
|
||||||
|
(dp(2, 32)..dp(2, 35), "selection"),
|
||||||
|
(dp(2, 32)..dp(2, 35), "match"),
|
||||||
|
(dp(2, 37)..dp(2, 40), "active"),
|
||||||
|
(dp(5, 6)..dp(5, 9), "selection"),
|
||||||
|
(dp(5, 6)..dp(5, 9), "match"),
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[perf]
|
#[perf]
|
||||||
|
|||||||
@@ -570,6 +570,9 @@ pub struct ThemeColorsContent {
|
|||||||
#[serde(rename = "search.match_background")]
|
#[serde(rename = "search.match_background")]
|
||||||
pub search_match_background: Option<String>,
|
pub search_match_background: Option<String>,
|
||||||
|
|
||||||
|
#[serde(rename = "search.active_match_background")]
|
||||||
|
pub search_active_match_background: Option<String>,
|
||||||
|
|
||||||
#[serde(rename = "panel.background")]
|
#[serde(rename = "panel.background")]
|
||||||
pub panel_background: Option<String>,
|
pub panel_background: Option<String>,
|
||||||
|
|
||||||
|
|||||||
@@ -1434,6 +1434,7 @@ impl SearchableItem for TerminalView {
|
|||||||
fn update_matches(
|
fn update_matches(
|
||||||
&mut self,
|
&mut self,
|
||||||
matches: &[Self::Match],
|
matches: &[Self::Match],
|
||||||
|
_active_match_index: Option<usize>,
|
||||||
_window: &mut Window,
|
_window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ impl ThemeColors {
|
|||||||
tab_inactive_background: neutral().light().step_2(),
|
tab_inactive_background: neutral().light().step_2(),
|
||||||
tab_active_background: neutral().light().step_1(),
|
tab_active_background: neutral().light().step_1(),
|
||||||
search_match_background: neutral().light().step_5(),
|
search_match_background: neutral().light().step_5(),
|
||||||
|
search_active_match_background: neutral().light().step_7(),
|
||||||
panel_background: neutral().light().step_2(),
|
panel_background: neutral().light().step_2(),
|
||||||
panel_focused_border: blue().light().step_10(),
|
panel_focused_border: blue().light().step_10(),
|
||||||
panel_indent_guide: neutral().light_alpha().step_5(),
|
panel_indent_guide: neutral().light_alpha().step_5(),
|
||||||
@@ -228,6 +229,7 @@ impl ThemeColors {
|
|||||||
tab_inactive_background: neutral().dark().step_2(),
|
tab_inactive_background: neutral().dark().step_2(),
|
||||||
tab_active_background: neutral().dark().step_1(),
|
tab_active_background: neutral().dark().step_1(),
|
||||||
search_match_background: neutral().dark().step_5(),
|
search_match_background: neutral().dark().step_5(),
|
||||||
|
search_active_match_background: neutral().dark().step_3(),
|
||||||
panel_background: neutral().dark().step_2(),
|
panel_background: neutral().dark().step_2(),
|
||||||
panel_focused_border: blue().dark().step_8(),
|
panel_focused_border: blue().dark().step_8(),
|
||||||
panel_indent_guide: neutral().dark_alpha().step_4(),
|
panel_indent_guide: neutral().dark_alpha().step_4(),
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ pub(crate) fn zed_default_dark() -> Theme {
|
|||||||
tab_inactive_background: bg,
|
tab_inactive_background: bg,
|
||||||
tab_active_background: editor,
|
tab_active_background: editor,
|
||||||
search_match_background: bg,
|
search_match_background: bg,
|
||||||
|
search_active_match_background: bg,
|
||||||
|
|
||||||
editor_background: editor,
|
editor_background: editor,
|
||||||
editor_gutter_background: editor,
|
editor_gutter_background: editor,
|
||||||
|
|||||||
@@ -287,6 +287,15 @@ pub fn theme_colors_refinement(
|
|||||||
.panel_background
|
.panel_background
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|color| try_parse_color(color).ok());
|
.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 {
|
ThemeColorsRefinement {
|
||||||
border,
|
border,
|
||||||
border_variant: this
|
border_variant: this
|
||||||
@@ -442,10 +451,8 @@ pub fn theme_colors_refinement(
|
|||||||
.tab_active_background
|
.tab_active_background
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
.and_then(|color| try_parse_color(color).ok()),
|
||||||
search_match_background: this
|
search_match_background: search_match_background,
|
||||||
.search_match_background
|
search_active_match_background: search_active_match_background,
|
||||||
.as_ref()
|
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
|
||||||
panel_background,
|
panel_background,
|
||||||
panel_focused_border: this
|
panel_focused_border: this
|
||||||
.panel_focused_border
|
.panel_focused_border
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ pub struct ThemeColors {
|
|||||||
pub tab_inactive_background: Hsla,
|
pub tab_inactive_background: Hsla,
|
||||||
pub tab_active_background: Hsla,
|
pub tab_active_background: Hsla,
|
||||||
pub search_match_background: Hsla,
|
pub search_match_background: Hsla,
|
||||||
|
pub search_active_match_background: Hsla,
|
||||||
pub panel_background: Hsla,
|
pub panel_background: Hsla,
|
||||||
pub panel_focused_border: Hsla,
|
pub panel_focused_border: Hsla,
|
||||||
pub panel_indent_guide: Hsla,
|
pub panel_indent_guide: Hsla,
|
||||||
@@ -352,6 +353,7 @@ pub enum ThemeColorField {
|
|||||||
TabInactiveBackground,
|
TabInactiveBackground,
|
||||||
TabActiveBackground,
|
TabActiveBackground,
|
||||||
SearchMatchBackground,
|
SearchMatchBackground,
|
||||||
|
SearchActiveMatchBackground,
|
||||||
PanelBackground,
|
PanelBackground,
|
||||||
PanelFocusedBorder,
|
PanelFocusedBorder,
|
||||||
PanelIndentGuide,
|
PanelIndentGuide,
|
||||||
@@ -467,6 +469,7 @@ impl ThemeColors {
|
|||||||
ThemeColorField::TabInactiveBackground => self.tab_inactive_background,
|
ThemeColorField::TabInactiveBackground => self.tab_inactive_background,
|
||||||
ThemeColorField::TabActiveBackground => self.tab_active_background,
|
ThemeColorField::TabActiveBackground => self.tab_active_background,
|
||||||
ThemeColorField::SearchMatchBackground => self.search_match_background,
|
ThemeColorField::SearchMatchBackground => self.search_match_background,
|
||||||
|
ThemeColorField::SearchActiveMatchBackground => self.search_active_match_background,
|
||||||
ThemeColorField::PanelBackground => self.panel_background,
|
ThemeColorField::PanelBackground => self.panel_background,
|
||||||
ThemeColorField::PanelFocusedBorder => self.panel_focused_border,
|
ThemeColorField::PanelFocusedBorder => self.panel_focused_border,
|
||||||
ThemeColorField::PanelIndentGuide => self.panel_indent_guide,
|
ThemeColorField::PanelIndentGuide => self.panel_indent_guide,
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ impl Vim {
|
|||||||
|
|
||||||
editor.highlight_background::<HighlightOnYank>(
|
editor.highlight_background::<HighlightOnYank>(
|
||||||
&ranges_to_highlight,
|
&ranges_to_highlight,
|
||||||
|colors| colors.colors().editor_document_highlight_read_background,
|
|_, colors| colors.colors().editor_document_highlight_read_background,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
cx.spawn(async move |this, cx| {
|
cx.spawn(async move |this, cx| {
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ impl Vim {
|
|||||||
let ranges = [new_range];
|
let ranges = [new_range];
|
||||||
editor.highlight_background::<VimExchange>(
|
editor.highlight_background::<VimExchange>(
|
||||||
&ranges,
|
&ranges,
|
||||||
|theme| theme.colors().editor_document_highlight_read_background,
|
|_, theme| theme.colors().editor_document_highlight_read_background,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ pub trait SearchableItem: Item + EventEmitter<SearchEvent> {
|
|||||||
fn update_matches(
|
fn update_matches(
|
||||||
&mut self,
|
&mut self,
|
||||||
matches: &[Self::Match],
|
matches: &[Self::Match],
|
||||||
|
active_match_index: Option<usize>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
);
|
);
|
||||||
@@ -179,7 +180,13 @@ pub trait SearchableItemHandle: ItemHandle {
|
|||||||
handler: Box<dyn Fn(&SearchEvent, &mut Window, &mut App) + Send>,
|
handler: Box<dyn Fn(&SearchEvent, &mut Window, &mut App) + Send>,
|
||||||
) -> Subscription;
|
) -> Subscription;
|
||||||
fn clear_matches(&self, window: &mut Window, cx: &mut App);
|
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 query_suggestion(&self, window: &mut Window, cx: &mut App) -> String;
|
||||||
fn activate_match(
|
fn activate_match(
|
||||||
&self,
|
&self,
|
||||||
@@ -264,10 +271,16 @@ impl<T: SearchableItem> SearchableItemHandle for Entity<T> {
|
|||||||
fn clear_matches(&self, window: &mut Window, cx: &mut App) {
|
fn clear_matches(&self, window: &mut Window, cx: &mut App) {
|
||||||
self.update(cx, |this, cx| this.clear_matches(window, cx));
|
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();
|
let matches = matches.downcast_ref().unwrap();
|
||||||
self.update(cx, |this, cx| {
|
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 {
|
fn query_suggestion(&self, window: &mut Window, cx: &mut App) -> String {
|
||||||
|
|||||||
Reference in New Issue
Block a user