diagnostics: Fix diagnostics pane clearing up too eagerly on typing (#37546)

Closes https://github.com/zed-industries/zed/issues/30494

Release Notes:

- Fixed diagnostics pane closing buffers too eagerly when typing inside
it
This commit is contained in:
Lukas Wirth
2025-09-04 15:30:23 +00:00
committed by GitHub
parent 1ae326432e
commit e37efc1e9b
2 changed files with 64 additions and 73 deletions
+38 -36
View File
@@ -94,43 +94,44 @@ impl Render for ProjectDiagnosticsEditor {
0
};
let child = if warning_count + self.summary.error_count == 0 {
let label = if self.summary.warning_count == 0 {
SharedString::new_static("No problems in workspace")
let child =
if warning_count + self.summary.error_count == 0 && self.editor.read(cx).is_empty(cx) {
let label = if self.summary.warning_count == 0 {
SharedString::new_static("No problems in workspace")
} else {
SharedString::new_static("No errors in workspace")
};
v_flex()
.key_context("EmptyPane")
.size_full()
.gap_1()
.justify_center()
.items_center()
.text_center()
.bg(cx.theme().colors().editor_background)
.child(Label::new(label).color(Color::Muted))
.when(self.summary.warning_count > 0, |this| {
let plural_suffix = if self.summary.warning_count > 1 {
"s"
} else {
""
};
let label = format!(
"Show {} warning{}",
self.summary.warning_count, plural_suffix
);
this.child(
Button::new("diagnostics-show-warning-label", label).on_click(
cx.listener(|this, _, window, cx| {
this.toggle_warnings(&Default::default(), window, cx);
cx.notify();
}),
),
)
})
} else {
SharedString::new_static("No errors in workspace")
div().size_full().child(self.editor.clone())
};
v_flex()
.key_context("EmptyPane")
.size_full()
.gap_1()
.justify_center()
.items_center()
.text_center()
.bg(cx.theme().colors().editor_background)
.child(Label::new(label).color(Color::Muted))
.when(self.summary.warning_count > 0, |this| {
let plural_suffix = if self.summary.warning_count > 1 {
"s"
} else {
""
};
let label = format!(
"Show {} warning{}",
self.summary.warning_count, plural_suffix
);
this.child(
Button::new("diagnostics-show-warning-label", label).on_click(cx.listener(
|this, _, window, cx| {
this.toggle_warnings(&Default::default(), window, cx);
cx.notify();
},
)),
)
})
} else {
div().size_full().child(self.editor.clone())
};
div()
.key_context("Diagnostics")
@@ -233,6 +234,7 @@ impl ProjectDiagnosticsEditor {
}
}
EditorEvent::Blurred => this.update_stale_excerpts(window, cx),
EditorEvent::Saved => this.update_stale_excerpts(window, cx),
_ => {}
}
},
@@ -277,7 +279,7 @@ impl ProjectDiagnosticsEditor {
}
fn update_stale_excerpts(&mut self, window: &mut Window, cx: &mut Context<Self>) {
if self.update_excerpts_task.is_some() {
if self.update_excerpts_task.is_some() || self.multibuffer.read(cx).is_dirty(cx) {
return;
}
+26 -37
View File
@@ -32,49 +32,38 @@ impl Render for DiagnosticIndicator {
}
let diagnostic_indicator = match (self.summary.error_count, self.summary.warning_count) {
(0, 0) => h_flex().map(|this| {
this.child(
Icon::new(IconName::Check)
.size(IconSize::Small)
.color(Color::Default),
)
}),
(0, warning_count) => h_flex()
.gap_1()
.child(
Icon::new(IconName::Warning)
.size(IconSize::Small)
.color(Color::Warning),
)
.child(Label::new(warning_count.to_string()).size(LabelSize::Small)),
(error_count, 0) => h_flex()
.gap_1()
.child(
Icon::new(IconName::XCircle)
.size(IconSize::Small)
.color(Color::Error),
)
.child(Label::new(error_count.to_string()).size(LabelSize::Small)),
(0, 0) => h_flex().child(
Icon::new(IconName::Check)
.size(IconSize::Small)
.color(Color::Default),
),
(error_count, warning_count) => h_flex()
.gap_1()
.child(
Icon::new(IconName::XCircle)
.size(IconSize::Small)
.color(Color::Error),
)
.child(Label::new(error_count.to_string()).size(LabelSize::Small))
.child(
Icon::new(IconName::Warning)
.size(IconSize::Small)
.color(Color::Warning),
)
.child(Label::new(warning_count.to_string()).size(LabelSize::Small)),
.when(error_count > 0, |this| {
this.child(
Icon::new(IconName::XCircle)
.size(IconSize::Small)
.color(Color::Error),
)
.child(Label::new(error_count.to_string()).size(LabelSize::Small))
})
.when(warning_count > 0, |this| {
this.child(
Icon::new(IconName::Warning)
.size(IconSize::Small)
.color(Color::Warning),
)
.child(Label::new(warning_count.to_string()).size(LabelSize::Small))
}),
};
let status = if let Some(diagnostic) = &self.current_diagnostic {
let message = diagnostic.message.split('\n').next().unwrap().to_string();
let message = diagnostic
.message
.split_once('\n')
.map_or(&*diagnostic.message, |(first, _)| first);
Some(
Button::new("diagnostic_message", message)
Button::new("diagnostic_message", SharedString::new(message))
.label_size(LabelSize::Small)
.tooltip(|window, cx| {
Tooltip::for_action(