diff --git a/Cargo.lock b/Cargo.lock index 05e25f42b8..987bd26572 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5716,6 +5716,7 @@ dependencies = [ "contacts_panel", "crossbeam-channel", "ctor", + "diagnostics", "dirs", "easy-parallel", "editor", diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index e076f34dd6..a562a33c35 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -1,23 +1,32 @@ use collections::HashMap; use editor::{Editor, ExcerptProperties, MultiBuffer}; -use gpui::{elements::*, Entity, ModelHandle, RenderContext, View, ViewContext, ViewHandle}; +use gpui::{ + action, elements::*, keymap::Binding, AppContext, Entity, ModelContext, ModelHandle, + MutableAppContext, RenderContext, View, ViewContext, ViewHandle, +}; use language::Point; use postage::watch; use project::Project; +use workspace::Workspace; + +action!(Toggle); + +pub fn init(cx: &mut MutableAppContext) { + cx.add_bindings([Binding::new("alt-shift-D", Toggle, None)]); + cx.add_action(ProjectDiagnosticsEditor::toggle); +} struct ProjectDiagnostics { - editor: ViewHandle, + excerpts: ModelHandle, project: ModelHandle, } -impl ProjectDiagnostics { - fn new( - project: ModelHandle, - settings: watch::Receiver, - cx: &mut ViewContext, - ) -> Self { - let buffer = cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id(cx))); +struct ProjectDiagnosticsEditor { + editor: ViewHandle, +} +impl ProjectDiagnostics { + fn new(project: ModelHandle, cx: &mut ModelContext) -> Self { let project_paths = project .read(cx) .diagnostic_summaries(cx) @@ -27,7 +36,6 @@ impl ProjectDiagnostics { cx.spawn(|this, mut cx| { let project = project.clone(); async move { - let mut excerpts = Vec::new(); for project_path in project_paths { let buffer = project .update(&mut cx, |project, cx| project.open_buffer(project_path, cx)) @@ -48,14 +56,20 @@ impl ProjectDiagnostics { grouped_diagnostics.into_values().collect::>(); sorted_diagnostic_groups.sort_by_key(|group| group.0); - let mut prev_end_row = None; - let mut pending_excerpt = None; for diagnostic in snapshot.all_diagnostics::() { - excerpts.push(ExcerptProperties { - buffer: &buffer, - range: todo!(), - header_height: todo!(), - }); + this.update(&mut cx, |this, cx| { + this.excerpts.update(cx, |excerpts, cx| { + excerpts.push_excerpt( + ExcerptProperties { + buffer: &buffer, + range: diagnostic.range, + header_height: 1, + }, + cx, + ); + cx.notify(); + }); + }) } } Result::Ok::<_, anyhow::Error>(()) @@ -64,13 +78,7 @@ impl ProjectDiagnostics { .detach(); Self { - editor: cx.add_view(|cx| { - Editor::for_buffer( - buffer.clone(), - editor::settings_builder(buffer.downgrade(), settings), - cx, - ) - }), + excerpts: cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id(cx))), project, } } @@ -80,12 +88,75 @@ impl Entity for ProjectDiagnostics { type Event = (); } -impl View for ProjectDiagnostics { +impl Entity for ProjectDiagnosticsEditor { + type Event = (); +} + +impl View for ProjectDiagnosticsEditor { fn ui_name() -> &'static str { - "ProjectDiagnostics" + "ProjectDiagnosticsEditor" } - fn render(&mut self, _: &mut RenderContext) -> ElementBox { + fn render(&mut self, cx: &mut RenderContext) -> ElementBox { ChildView::new(self.editor.id()).boxed() } } + +impl ProjectDiagnosticsEditor { + fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { + dbg!("HEY!!!!"); + let diagnostics = + cx.add_model(|cx| ProjectDiagnostics::new(workspace.project().clone(), cx)); + workspace.add_item(diagnostics, cx); + } +} + +impl workspace::Item for ProjectDiagnostics { + type View = ProjectDiagnosticsEditor; + + fn build_view( + handle: ModelHandle, + settings: watch::Receiver, + cx: &mut ViewContext, + ) -> Self::View { + let excerpts = handle.read(cx).excerpts.clone(); + let editor = cx.add_view(|cx| { + Editor::for_buffer( + excerpts.clone(), + editor::settings_builder(excerpts.downgrade(), settings), + cx, + ) + }); + ProjectDiagnosticsEditor { editor } + } + + fn project_path(&self) -> Option { + None + } +} + +impl workspace::ItemView for ProjectDiagnosticsEditor { + fn title(&self, _: &AppContext) -> String { + "Project Diagnostics".to_string() + } + + fn project_path(&self, cx: &AppContext) -> Option { + None + } + + fn save( + &mut self, + cx: &mut ViewContext, + ) -> anyhow::Result>> { + todo!() + } + + fn save_as( + &mut self, + worktree: ModelHandle, + path: &std::path::Path, + cx: &mut ViewContext, + ) -> gpui::Task> { + todo!() + } +} diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index e03ef6dcf9..275f8b0deb 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -32,6 +32,7 @@ text = { path = "../text" } chat_panel = { path = "../chat_panel" } client = { path = "../client" } clock = { path = "../clock" } +diagnostics = { path = "../diagnostics" } fsevent = { path = "../fsevent" } fuzzy = { path = "../fuzzy" } editor = { path = "../editor" } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index c6374c66e7..3847244ba6 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -59,6 +59,7 @@ fn main() { contacts_panel::init(cx); chat_panel::init(cx); project_panel::init(cx); + diagnostics::init(cx); let app_state = Arc::new(AppState { languages: languages.clone(),