mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-12 05:27:07 +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 anyhow::Result;
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
use editor::{
|
use editor::{
|
||||||
|
@ -16,13 +18,13 @@ use std::{cmp::Ordering, ops::Range, path::Path, sync::Arc};
|
||||||
use util::TryFutureExt;
|
use util::TryFutureExt;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
action!(Toggle);
|
action!(Deploy);
|
||||||
|
|
||||||
const CONTEXT_LINE_COUNT: u32 = 1;
|
const CONTEXT_LINE_COUNT: u32 = 1;
|
||||||
|
|
||||||
pub fn init(cx: &mut MutableAppContext) {
|
pub fn init(cx: &mut MutableAppContext) {
|
||||||
cx.add_bindings([Binding::new("alt-shift-D", Toggle, None)]);
|
cx.add_bindings([Binding::new("alt-shift-D", Deploy, None)]);
|
||||||
cx.add_action(ProjectDiagnosticsEditor::toggle);
|
cx.add_action(ProjectDiagnosticsEditor::deploy);
|
||||||
}
|
}
|
||||||
|
|
||||||
type Event = editor::Event;
|
type Event = editor::Event;
|
||||||
|
@ -148,7 +150,7 @@ impl ProjectDiagnosticsEditor {
|
||||||
self.editor.read(cx).text(cx)
|
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()));
|
let diagnostics = cx.add_model(|_| ProjectDiagnostics::new(workspace.project().clone()));
|
||||||
workspace.add_item(diagnostics, cx);
|
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>(
|
pub fn diagnostic_summaries<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
cx: &'a AppContext,
|
cx: &'a AppContext,
|
||||||
|
|
|
@ -232,6 +232,7 @@ pub struct ProjectDiagnostics {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub container: ContainerStyle,
|
pub container: ContainerStyle,
|
||||||
pub empty_message: TextStyle,
|
pub empty_message: TextStyle,
|
||||||
|
pub status_bar_item: ContainedText,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Default)]
|
#[derive(Clone, Deserialize, Default)]
|
||||||
|
|
|
@ -185,7 +185,7 @@ corner_radius = 6
|
||||||
|
|
||||||
[project_panel]
|
[project_panel]
|
||||||
extends = "$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]
|
[project_panel.entry]
|
||||||
text = "$text.1"
|
text = "$text.1"
|
||||||
|
@ -273,3 +273,4 @@ header = { padding = { left = 10 }, background = "#ffffff08" }
|
||||||
[project_diagnostics]
|
[project_diagnostics]
|
||||||
background = "$surface.1"
|
background = "$surface.1"
|
||||||
empty_message = "$text.0"
|
empty_message = "$text.0"
|
||||||
|
status_bar_item = { extends = "$text.2", margin.right = 10 }
|
||||||
|
|
|
@ -88,12 +88,20 @@ pub fn build_workspace(
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let diagnostic =
|
let diagnostic_message =
|
||||||
cx.add_view(|_| editor::items::DiagnosticMessage::new(app_state.settings.clone()));
|
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 =
|
let cursor_position =
|
||||||
cx.add_view(|_| editor::items::CursorPosition::new(app_state.settings.clone()));
|
cx.add_view(|_| editor::items::CursorPosition::new(app_state.settings.clone()));
|
||||||
workspace.status_bar().update(cx, |status_bar, cx| {
|
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);
|
status_bar.add_right_item(cursor_position, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue