Cargo.lock 🔗
@@ -1414,8 +1414,11 @@ dependencies = [
name = "diagnostics"
version = "0.1.0"
dependencies = [
+ "anyhow",
+ "collections",
"editor",
"gpui",
+ "language",
"postage",
"project",
"workspace",
Max Brunsfeld created
Cargo.lock | 3 +
crates/diagnostics/Cargo.toml | 3 +
crates/diagnostics/src/diagnostics.rs | 54 ++++++++++++++++++++++++++--
crates/editor/src/editor.rs | 2
crates/editor/src/multi_buffer.rs | 6 +-
crates/language/src/buffer.rs | 9 ++++
6 files changed, 68 insertions(+), 9 deletions(-)
@@ -1414,8 +1414,11 @@ dependencies = [
name = "diagnostics"
version = "0.1.0"
dependencies = [
+ "anyhow",
+ "collections",
"editor",
"gpui",
+ "language",
"postage",
"project",
"workspace",
@@ -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" }
@@ -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<workspace::Settings>,
cx: &mut ViewContext<Self>,
) -> 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::<Vec<_>>();
+
+ 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::<Vec<_>>();
+ 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::<Point>() {
+ excerpts.push(ExcerptProperties {
+ buffer: &buffer,
+ range: todo!(),
+ header_height: todo!(),
+ });
+ }
+ }
+ Result::Ok::<_, anyhow::Error>(())
+ }
+ })
+ .detach();
Self {
editor: cx.add_view(|cx| {
@@ -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;
@@ -65,9 +65,9 @@ pub struct MultiBufferSnapshot {
}
pub struct ExcerptProperties<'a, T> {
- buffer: &'a ModelHandle<Buffer>,
- range: Range<T>,
- header_height: u8,
+ pub buffer: &'a ModelHandle<Buffer>,
+ pub range: Range<T>,
+ pub header_height: u8,
}
#[derive(Clone)]
@@ -1674,6 +1674,15 @@ impl BufferSnapshot {
})
}
+ pub fn all_diagnostics<'a, O>(&'a self) -> impl 'a + Iterator<Item = DiagnosticEntry<O>>
+ 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<T>,