mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-11 21:00:35 +00:00
Show status bar item for project diagnostic summary
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
56496c2585
commit
e39be35e17
6 changed files with 101 additions and 7 deletions
|
@ -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);
|
||||
}
|
||||
|
|
71
crates/diagnostics/src/items.rs
Normal file
71
crates/diagnostics/src/items.rs
Normal 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>,
|
||||
) {
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue