Detailed changes
@@ -1,3 +1,5 @@
+pub mod items;
+
use anyhow::Result;
use collections::{HashMap, HashSet};
use editor::{
@@ -16,13 +18,13 @@ use std::{cmp::Ordering, ops::Range, path::Path, sync::Arc};
use util::TryFutureExt;
use workspace::Workspace;
-action!(Toggle);
+action!(Deploy);
const CONTEXT_LINE_COUNT: u32 = 1;
pub fn init(cx: &mut MutableAppContext) {
- cx.add_bindings([Binding::new("alt-shift-D", Toggle, None)]);
- cx.add_action(ProjectDiagnosticsEditor::toggle);
+ cx.add_bindings([Binding::new("alt-shift-D", Deploy, None)]);
+ cx.add_action(ProjectDiagnosticsEditor::deploy);
}
type Event = editor::Event;
@@ -148,7 +150,7 @@ impl ProjectDiagnosticsEditor {
self.editor.read(cx).text(cx)
}
- fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) {
+ fn deploy(workspace: &mut Workspace, _: &Deploy, cx: &mut ViewContext<Workspace>) {
let diagnostics = cx.add_model(|_| ProjectDiagnostics::new(workspace.project().clone()));
workspace.add_item(diagnostics, cx);
}
@@ -0,0 +1,71 @@
+use gpui::{
+ elements::*, platform::CursorStyle, Entity, ModelHandle, RenderContext, View, ViewContext,
+};
+use postage::watch;
+use project::Project;
+use workspace::{Settings, StatusItemView};
+
+pub struct DiagnosticSummary {
+ settings: watch::Receiver<Settings>,
+ summary: project::DiagnosticSummary,
+}
+
+impl DiagnosticSummary {
+ pub fn new(
+ project: &ModelHandle<Project>,
+ settings: watch::Receiver<Settings>,
+ cx: &mut ViewContext<Self>,
+ ) -> Self {
+ cx.subscribe(project, |this, project, event, cx| {
+ if let project::Event::DiskBasedDiagnosticsUpdated { .. } = event {
+ this.summary = project.read(cx).diagnostic_summary(cx);
+ cx.notify();
+ }
+ })
+ .detach();
+ Self {
+ settings,
+ summary: project.read(cx).diagnostic_summary(cx),
+ }
+ }
+}
+
+impl Entity for DiagnosticSummary {
+ type Event = ();
+}
+
+impl View for DiagnosticSummary {
+ fn ui_name() -> &'static str {
+ "DiagnosticSummary"
+ }
+
+ fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
+ enum Tag {}
+
+ let theme = &self.settings.borrow().theme.project_diagnostics;
+ MouseEventHandler::new::<Tag, _, _, _>(0, cx, |_, _| {
+ Label::new(
+ format!(
+ "Errors: {}, Warnings: {}",
+ self.summary.error_count, self.summary.warning_count
+ ),
+ theme.status_bar_item.text.clone(),
+ )
+ .contained()
+ .with_style(theme.status_bar_item.container)
+ .boxed()
+ })
+ .with_cursor_style(CursorStyle::PointingHand)
+ .on_click(|cx| cx.dispatch_action(crate::Deploy))
+ .boxed()
+ }
+}
+
+impl StatusItemView for DiagnosticSummary {
+ fn set_active_pane_item(
+ &mut self,
+ _: Option<&dyn workspace::ItemViewHandle>,
+ _: &mut ViewContext<Self>,
+ ) {
+ }
+}
@@ -539,6 +539,17 @@ impl Project {
}
}
+ pub fn diagnostic_summary(&self, cx: &AppContext) -> DiagnosticSummary {
+ let mut summary = DiagnosticSummary::default();
+ for (_, path_summary) in self.diagnostic_summaries(cx) {
+ summary.error_count += path_summary.error_count;
+ summary.warning_count += path_summary.warning_count;
+ summary.info_count += path_summary.info_count;
+ summary.hint_count += path_summary.hint_count;
+ }
+ summary
+ }
+
pub fn diagnostic_summaries<'a>(
&'a self,
cx: &'a AppContext,
@@ -232,6 +232,7 @@ pub struct ProjectDiagnostics {
#[serde(flatten)]
pub container: ContainerStyle,
pub empty_message: TextStyle,
+ pub status_bar_item: ContainedText,
}
#[derive(Clone, Deserialize, Default)]
@@ -185,7 +185,7 @@ corner_radius = 6
[project_panel]
extends = "$panel"
-padding.top = 6 # ($workspace.tab.height - $project_panel.entry.height) / 2
+padding.top = 6 # ($workspace.tab.height - $project_panel.entry.height) / 2
[project_panel.entry]
text = "$text.1"
@@ -273,3 +273,4 @@ header = { padding = { left = 10 }, background = "#ffffff08" }
[project_diagnostics]
background = "$surface.1"
empty_message = "$text.0"
+status_bar_item = { extends = "$text.2", margin.right = 10 }
@@ -88,12 +88,20 @@ pub fn build_workspace(
.into(),
);
- let diagnostic =
+ let diagnostic_message =
cx.add_view(|_| editor::items::DiagnosticMessage::new(app_state.settings.clone()));
+ let diagnostic_summary = cx.add_view(|cx| {
+ diagnostics::items::DiagnosticSummary::new(
+ workspace.project(),
+ app_state.settings.clone(),
+ cx,
+ )
+ });
let cursor_position =
cx.add_view(|_| editor::items::CursorPosition::new(app_state.settings.clone()));
workspace.status_bar().update(cx, |status_bar, cx| {
- status_bar.add_left_item(diagnostic, cx);
+ status_bar.add_left_item(diagnostic_summary, cx);
+ status_bar.add_left_item(diagnostic_message, cx);
status_bar.add_right_item(cursor_position, cx);
});