Show status bar item for project diagnostic summary

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2022-01-07 14:06:05 +01:00
parent 56496c2585
commit e39be35e17
6 changed files with 101 additions and 7 deletions

View File

@ -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);
}

View File

@ -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>,
) {
}
}

View File

@ -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,

View File

@ -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)]

View File

@ -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 }

View File

@ -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);
});