diff --git a/Cargo.lock b/Cargo.lock index 0a2cf5ad04..05e25f42b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1414,8 +1414,11 @@ dependencies = [ name = "diagnostics" version = "0.1.0" dependencies = [ + "anyhow", + "collections", "editor", "gpui", + "language", "postage", "project", "workspace", diff --git a/crates/diagnostics/Cargo.toml b/crates/diagnostics/Cargo.toml index 6f9979a22e..eebe4b2091 100644 --- a/crates/diagnostics/Cargo.toml +++ b/crates/diagnostics/Cargo.toml @@ -7,7 +7,10 @@ edition = "2021" path = "src/diagnostics.rs" [dependencies] +anyhow = "1.0" +collections = { path = "../collections" } editor = { path = "../editor" } +language = { path = "../language" } gpui = { path = "../gpui" } project = { path = "../project" } workspace = { path = "../workspace" } diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 1162dccc78..e076f34dd6 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -1,5 +1,7 @@ -use editor::{Editor, MultiBuffer}; +use collections::HashMap; +use editor::{Editor, ExcerptProperties, MultiBuffer}; use gpui::{elements::*, Entity, ModelHandle, RenderContext, View, ViewContext, ViewHandle}; +use language::Point; use postage::watch; use project::Project; @@ -14,10 +16,52 @@ impl ProjectDiagnostics { settings: watch::Receiver, cx: &mut ViewContext, ) -> Self { - let mut buffer = cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id(cx))); - for (project_path, diagnostic_summary) in project.read(cx).diagnostic_summaries(cx) { - // - } + let buffer = cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id(cx))); + + let project_paths = project + .read(cx) + .diagnostic_summaries(cx) + .map(|e| e.0) + .collect::>(); + + 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)) + .await?; + let snapshot = buffer.read_with(&cx, |b, _| b.snapshot()); + + let mut grouped_diagnostics = HashMap::default(); + for entry in snapshot.all_diagnostics() { + let mut group = grouped_diagnostics + .entry(entry.diagnostic.group_id) + .or_insert((Point::zero(), Vec::new())); + if entry.diagnostic.is_primary { + group.0 = entry.range.start; + } + group.1.push(entry); + } + let mut sorted_diagnostic_groups = + 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!(), + }); + } + } + Result::Ok::<_, anyhow::Error>(()) + } + }) + .detach(); Self { editor: cx.add_view(|cx| { diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 0eecd17ce6..4bb1195504 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -26,10 +26,10 @@ use language::{ BracketPair, Buffer, Diagnostic, DiagnosticSeverity, Language, Point, Selection, SelectionGoal, TransactionId, }; -pub use multi_buffer::MultiBuffer; use multi_buffer::{ Anchor, AnchorRangeExt, MultiBufferChunks, MultiBufferSnapshot, ToOffset, ToPoint, }; +pub use multi_buffer::{ExcerptProperties, MultiBuffer}; use postage::watch; use serde::{Deserialize, Serialize}; use smallvec::SmallVec; diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index d79c074906..c7e8eeacf5 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -65,9 +65,9 @@ pub struct MultiBufferSnapshot { } pub struct ExcerptProperties<'a, T> { - buffer: &'a ModelHandle, - range: Range, - header_height: u8, + pub buffer: &'a ModelHandle, + pub range: Range, + pub header_height: u8, } #[derive(Clone)] diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 4b518467aa..92539c49ba 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -1674,6 +1674,15 @@ impl BufferSnapshot { }) } + pub fn all_diagnostics<'a, O>(&'a self) -> impl 'a + Iterator> + where + O: 'a + FromAnchor, + { + self.diagnostics + .iter() + .map(|diagnostic| diagnostic.resolve(self)) + } + pub fn diagnostics_in_range<'a, T, O>( &'a self, search_range: Range,