Render diagnostics view and such a bit more

This commit is contained in:
Julia 2023-11-17 12:54:34 -05:00
parent c6d22af416
commit 967ef9d414
9 changed files with 100 additions and 127 deletions

1
Cargo.lock generated
View File

@ -11474,6 +11474,7 @@ dependencies = [
"copilot2",
"ctor",
"db2",
"diagnostics2",
"editor2",
"env_logger 0.9.3",
"feature_flags2",

View File

@ -116,6 +116,7 @@ impl Clone for Command {
}
}
}
/// Hit count for each command in the palette.
/// We only account for commands triggered directly via command palette and not by e.g. keystrokes because
/// if an user already knows a keystroke for a command, they are unlikely to use a command palette to look for it.

View File

@ -14,8 +14,9 @@ use editor::{
use futures::future::try_join_all;
use gpui::{
actions, div, AnyElement, AnyView, AppContext, Component, Context, Div, EventEmitter,
FocusHandle, InteractiveComponent, Model, ParentComponent, Render, SharedString, Styled,
Subscription, Task, View, ViewContext, VisualContext, WeakView,
FocusEvent, FocusHandle, Focusable, FocusableComponent, InteractiveComponent, Model,
ParentComponent, Render, SharedString, Styled, Subscription, Task, View, ViewContext,
VisualContext, WeakView,
};
use language::{
Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection,
@ -48,9 +49,8 @@ const CONTEXT_LINE_COUNT: u32 = 1;
pub fn init(cx: &mut AppContext) {
ProjectDiagnosticsSettings::register(cx);
// todo!()
// cx.add_action(ProjectDiagnosticsEditor::deploy);
// cx.add_action(ProjectDiagnosticsEditor::toggle_warnings);
cx.observe_new_views(ProjectDiagnosticsEditor::register)
.detach();
}
struct ProjectDiagnosticsEditor {
@ -91,39 +91,34 @@ struct DiagnosticGroupState {
impl EventEmitter<ItemEvent> for ProjectDiagnosticsEditor {}
impl Render for ProjectDiagnosticsEditor {
type Element = Div<Self>;
type Element = Focusable<Self, Div<Self>>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
div().size_full().bg(gpui::red())
fn render(&mut self, _: &mut ViewContext<Self>) -> Self::Element {
let child = if self.path_states.is_empty() {
div()
.flex()
.items_center()
.justify_center()
.size_full()
.child(Label::new("No problems in workspace"))
} else {
div().size_full().child(self.editor.clone())
};
div()
.track_focus(&self.focus_handle)
.size_full()
.on_focus_in(Self::focus_in)
.on_action(Self::toggle_warnings)
.child(child)
}
}
// impl View for ProjectDiagnosticsEditor {
// fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
// if self.path_states.is_empty() {
// let theme = &theme::current(cx).project_diagnostics;
// PaneBackdrop::new(
// cx.view_id(),
// Label::new("No problems in workspace", theme.empty_message.clone())
// .aligned()
// .contained()
// .with_style(theme.container)
// .into_any(),
// )
// .into_any()
// } else {
// ChildView::new(&self.editor, cx).into_any()
// }
// }
// fn focus_in(&mut self, _: AnyView, cx: &mut ViewContext<Self>) {
// if cx.is_self_focused() && !self.path_states.is_empty() {
// cx.focus(&self.editor);
// }
// }
// }
impl ProjectDiagnosticsEditor {
fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
workspace.register_action(Self::deploy);
}
fn new(
project_handle: Model<Project>,
workspace: WeakView<Workspace>,
@ -240,6 +235,12 @@ impl ProjectDiagnosticsEditor {
cx.notify();
}
fn focus_in(&mut self, _: &FocusEvent, cx: &mut ViewContext<Self>) {
if self.focus_handle.is_focused(cx) && !self.path_states.is_empty() {
self.editor.focus_handle(cx).focus(cx)
}
}
fn update_excerpts(
&mut self,
language_server_id: Option<LanguageServerId>,

View File

@ -1,20 +1,18 @@
use collections::HashSet;
use editor::{Editor, GoToDiagnostic};
use gpui::{
div, serde_json, AppContext, CursorStyle, Div, Entity, EventEmitter, MouseButton, Render,
Styled, Subscription, View, ViewContext, WeakView,
div, serde_json, svg, AppContext, CursorStyle, Div, Entity, EventEmitter, InteractiveComponent,
MouseButton, ParentComponent, Render, Stateful, Styled, Subscription, Svg, View, ViewContext,
WeakView,
};
use language::Diagnostic;
use lsp::LanguageServerId;
use theme::ActiveTheme;
use ui::{Icon, IconElement, Label, TextColor};
use workspace::{item::ItemHandle, StatusItemView, ToolbarItemEvent, Workspace};
use crate::ProjectDiagnosticsEditor;
// todo!()
// pub fn init(cx: &mut AppContext) {
// cx.add_action(DiagnosticIndicator::go_to_next_diagnostic);
// }
pub struct DiagnosticIndicator {
summary: project::DiagnosticSummary,
active_editor: Option<WeakView<Editor>>,
@ -25,10 +23,33 @@ pub struct DiagnosticIndicator {
}
impl Render for DiagnosticIndicator {
type Element = Div<Self>;
type Element = Stateful<Self, Div<Self>>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
div().size_full().bg(gpui::red())
let mut summary_row = div().flex().flex_row().size_full();
if self.summary.error_count > 0 {
summary_row =
summary_row.child(IconElement::new(Icon::XCircle).color(TextColor::Error));
summary_row = summary_row.child(Label::new(self.summary.error_count.to_string()));
}
if self.summary.warning_count > 0 {
summary_row = summary_row
.child(IconElement::new(Icon::ExclamationTriangle).color(TextColor::Warning));
summary_row = summary_row.child(Label::new(self.summary.warning_count.to_string()));
}
if self.summary.error_count == 0 && self.summary.warning_count == 0 {
summary_row =
summary_row.child(IconElement::new(Icon::Check).color(TextColor::Success));
}
div()
.id(cx.entity_id())
.on_action(Self::go_to_next_diagnostic)
.size_full()
.child(summary_row)
}
}
@ -40,19 +61,23 @@ impl DiagnosticIndicator {
this.in_progress_checks.insert(*language_server_id);
cx.notify();
}
project::Event::DiskBasedDiagnosticsFinished { language_server_id }
| project::Event::LanguageServerRemoved(language_server_id) => {
this.summary = project.read(cx).diagnostic_summary(cx);
this.in_progress_checks.remove(language_server_id);
cx.notify();
}
project::Event::DiagnosticsUpdated { .. } => {
this.summary = project.read(cx).diagnostic_summary(cx);
cx.notify();
}
_ => {}
})
.detach();
Self {
summary: project.read(cx).diagnostic_summary(cx),
in_progress_checks: project

View File

@ -14,50 +14,35 @@ impl Render for ToolbarControls {
type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
div()
.h_flex()
.child(IconButton::new("toggle-warnings", Icon::Warning).on_click(|view, cx| todo!()))
let include_warnings = self
.editor
.as_ref()
.and_then(|editor| editor.upgrade())
.map(|editor| editor.read(cx).include_warnings)
.unwrap_or(false);
let tooltip = if include_warnings {
"Exclude Warnings"
} else {
"Include Warnings"
};
div().child(
IconButton::new("toggle-warnings", Icon::ExclamationTriangle)
.tooltip(tooltip)
.on_click(|this: &mut Self, cx| {
if let Some(editor) = this.editor.as_ref().and_then(|editor| editor.upgrade()) {
editor.update(cx, |editor, cx| {
editor.toggle_warnings(&Default::default(), cx);
});
}
}),
)
}
}
impl EventEmitter<ToolbarItemEvent> for ToolbarControls {}
// impl View for ToolbarControls {
// fn ui_name() -> &'static str {
// "ToolbarControls"
// }
// fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
// let include_warnings = self
// .editor
// .as_ref()
// .and_then(|editor| editor.upgrade(cx))
// .map(|editor| editor.read(cx).include_warnings)
// .unwrap_or(false);
// let tooltip = if include_warnings {
// "Exclude Warnings".into()
// } else {
// "Include Warnings".into()
// };
// Flex::row()
// .with_child(render_toggle_button(
// 0,
// "icons/warning.svg",
// include_warnings,
// (tooltip, Some(Box::new(ToggleWarnings))),
// cx,
// move |this, cx| {
// if let Some(editor) = this.editor.and_then(|editor| editor.upgrade(cx)) {
// editor.update(cx, |editor, cx| {
// editor.toggle_warnings(&Default::default(), cx)
// });
// }
// },
// ))
// .into_any()
// }
// }
impl ToolbarItemView for ToolbarControls {
fn set_active_pane_item(
&mut self,
@ -82,42 +67,3 @@ impl ToolbarControls {
ToolbarControls { editor: None }
}
}
// fn render_toggle_button<
// F: 'static + Fn(&mut ToolbarControls, &mut EventContext<ToolbarControls>),
// >(
// index: usize,
// icon: &'static str,
// toggled: bool,
// tooltip: (String, Option<Box<dyn Action>>),
// cx: &mut ViewContext<ToolbarControls>,
// on_click: F,
// ) -> AnyElement<ToolbarControls> {
// enum Button {}
// let theme = theme::current(cx);
// let (tooltip_text, action) = tooltip;
// MouseEventHandler::new::<Button, _>(index, cx, |mouse_state, _| {
// let style = theme
// .workspace
// .toolbar
// .toggleable_tool
// .in_state(toggled)
// .style_for(mouse_state);
// Svg::new(icon)
// .with_color(style.color)
// .constrained()
// .with_width(style.icon_width)
// .aligned()
// .constrained()
// .with_width(style.button_width)
// .with_height(style.button_width)
// .contained()
// .with_style(style.container)
// })
// .with_cursor_style(CursorStyle::PointingHand)
// .on_click(MouseButton::Left, move |_, view, cx| on_click(view, cx))
// .with_tooltip::<Button>(index, tooltip_text, action, theme.tooltip.clone(), cx)
// .into_any_named("quick action bar button")
// }

View File

@ -64,7 +64,6 @@ pub enum Icon {
Split,
SplitMessage,
Terminal,
Warning,
XCircle,
}
@ -123,7 +122,6 @@ impl Icon {
Icon::Split => "icons/split.svg",
Icon::SplitMessage => "icons/split_message.svg",
Icon::Terminal => "icons/terminal.svg",
Icon::Warning => "icons/warning.svg",
Icon::XCircle => "icons/error.svg",
}
}

View File

@ -32,7 +32,7 @@ client = { package = "client2", path = "../client2" }
# clock = { path = "../clock" }
copilot = { package = "copilot2", path = "../copilot2" }
# copilot_button = { path = "../copilot_button" }
# diagnostics = { path = "../diagnostics" }
diagnostics = { package = "diagnostics2", path = "../diagnostics2" }
db = { package = "db2", path = "../db2" }
editor = { package="editor2", path = "../editor2" }
# feedback = { path = "../feedback" }

View File

@ -147,6 +147,7 @@ fn main() {
command_palette::init(cx);
language::init(cx);
editor::init(cx);
diagnostics::init(cx);
copilot::init(
copilot_language_server_id,
http.clone(),

View File

@ -314,8 +314,8 @@ pub fn initialize_workspace(
// QuickActionBar::new(buffer_search_bar, workspace)
// });
// toolbar.add_item(quick_action_bar, cx);
// let diagnostic_editor_controls =
// cx.add_view(|_| diagnostics2::ToolbarControls::new());
let diagnostic_editor_controls =
cx.build_view(|_| diagnostics::ToolbarControls::new());
// toolbar.add_item(diagnostic_editor_controls, cx);
// let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
// toolbar.add_item(project_search_bar, cx);
@ -347,8 +347,8 @@ pub fn initialize_workspace(
// let copilot =
// cx.add_view(|cx| copilot_button::CopilotButton::new(app_state.fs.clone(), cx));
// let diagnostic_summary =
// cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
let diagnostic_summary =
cx.build_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
// let activity_indicator = activity_indicator::ActivityIndicator::new(
// workspace,
// app_state.languages.clone(),