Fix invalid regular expressions highlighting all search fields (#35001)

Closes https://github.com/zed-industries/zed/issues/34969
Closes https://github.com/zed-industries/zed/issues/34970

Only highlight the search field on regex error (buffer search and
project search).
Clear errors when the buffer search hidden so stale errors aren't shown
on next search.

Before (all fields highlighted red): 
<img width="631" height="180" alt="Screenshot 2025-07-23 at 22 59 45"
src="https://github.com/user-attachments/assets/a91d3090-1bae-4718-a1f5-0a1237559ff2"
/>

After (only query field highlighted red): 
<img width="632" height="187" alt="Screenshot 2025-07-23 at 23 10 49"
src="https://github.com/user-attachments/assets/6ae72c84-9333-4cdb-907b-afb7a0a6e808"
/>

Release Notes:

- Improved highlighting of regex errors in search dialogs
This commit is contained in:
Peter Tripp 2025-07-24 09:20:25 -04:00 committed by GitHub
parent 4fb540d6d2
commit fab450e39d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 15 deletions

View file

@ -228,16 +228,17 @@ impl Render for BufferSearchBar {
if in_replace {
key_context.add("in_replace");
}
let editor_border = if self.query_error.is_some() {
let query_border = if self.query_error.is_some() {
Color::Error.color(cx)
} else {
cx.theme().colors().border
};
let replacement_border = cx.theme().colors().border;
let container_width = window.viewport_size().width;
let input_width = SearchInputWidth::calc_width(container_width);
let input_base_styles = || {
let input_base_styles = |border_color| {
h_flex()
.min_w_32()
.w(input_width)
@ -246,7 +247,7 @@ impl Render for BufferSearchBar {
.pr_1()
.py_1()
.border_1()
.border_color(editor_border)
.border_color(border_color)
.rounded_lg()
};
@ -256,7 +257,7 @@ impl Render for BufferSearchBar {
el.child(Label::new("Find in results").color(Color::Hint))
})
.child(
input_base_styles()
input_base_styles(query_border)
.id("editor-scroll")
.track_scroll(&self.editor_scroll_handle)
.child(self.render_text_input(&self.query_editor, color_override, cx))
@ -430,11 +431,13 @@ impl Render for BufferSearchBar {
let replace_line = should_show_replace_input.then(|| {
h_flex()
.gap_2()
.child(input_base_styles().child(self.render_text_input(
&self.replacement_editor,
None,
cx,
)))
.child(
input_base_styles(replacement_border).child(self.render_text_input(
&self.replacement_editor,
None,
cx,
)),
)
.child(
h_flex()
.min_w_64()
@ -775,6 +778,7 @@ impl BufferSearchBar {
pub fn dismiss(&mut self, _: &Dismiss, window: &mut Window, cx: &mut Context<Self>) {
self.dismissed = true;
self.query_error = None;
for searchable_item in self.searchable_items_with_matches.keys() {
if let Some(searchable_item) =
WeakSearchableItemHandle::upgrade(searchable_item.as_ref(), cx)

View file

@ -195,6 +195,7 @@ pub struct ProjectSearch {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum InputPanel {
Query,
Replacement,
Exclude,
Include,
}
@ -1962,7 +1963,7 @@ impl Render for ProjectSearchBar {
MultipleInputs,
}
let input_base_styles = |base_style: BaseStyle| {
let input_base_styles = |base_style: BaseStyle, panel: InputPanel| {
h_flex()
.min_w_32()
.map(|div| match base_style {
@ -1974,11 +1975,11 @@ impl Render for ProjectSearchBar {
.pr_1()
.py_1()
.border_1()
.border_color(search.border_color_for(InputPanel::Query, cx))
.border_color(search.border_color_for(panel, cx))
.rounded_lg()
};
let query_column = input_base_styles(BaseStyle::SingleInput)
let query_column = input_base_styles(BaseStyle::SingleInput, InputPanel::Query)
.on_action(cx.listener(|this, action, window, cx| this.confirm(action, window, cx)))
.on_action(cx.listener(|this, action, window, cx| {
this.previous_history_query(action, window, cx)
@ -2167,7 +2168,7 @@ impl Render for ProjectSearchBar {
.child(h_flex().min_w_64().child(mode_column).child(matches_column));
let replace_line = search.replace_enabled.then(|| {
let replace_column = input_base_styles(BaseStyle::SingleInput)
let replace_column = input_base_styles(BaseStyle::SingleInput, InputPanel::Replacement)
.child(self.render_text_input(&search.replacement_editor, cx));
let focus_handle = search.replacement_editor.read(cx).focus_handle(cx);
@ -2241,7 +2242,7 @@ impl Render for ProjectSearchBar {
.gap_2()
.w(input_width)
.child(
input_base_styles(BaseStyle::MultipleInputs)
input_base_styles(BaseStyle::MultipleInputs, InputPanel::Include)
.on_action(cx.listener(|this, action, window, cx| {
this.previous_history_query(action, window, cx)
}))
@ -2251,7 +2252,7 @@ impl Render for ProjectSearchBar {
.child(self.render_text_input(&search.included_files_editor, cx)),
)
.child(
input_base_styles(BaseStyle::MultipleInputs)
input_base_styles(BaseStyle::MultipleInputs, InputPanel::Exclude)
.on_action(cx.listener(|this, action, window, cx| {
this.previous_history_query(action, window, cx)
}))