diff --git a/crates/buffer/src/anchor.rs b/crates/buffer/src/anchor.rs index bb0e7b386a..ceee746c6a 100644 --- a/crates/buffer/src/anchor.rs +++ b/crates/buffer/src/anchor.rs @@ -354,6 +354,38 @@ impl AnchorRangeMultimap { .cursor::<()>() .map(|entry| (entry.range.start..entry.range.end, &entry.value)) } + + pub fn filter<'a, O, F>( + &'a self, + content: Content<'a>, + mut f: F, + ) -> impl 'a + Iterator, &T)> + where + O: FromAnchor, + F: 'a + FnMut(&'a T) -> bool, + { + let mut endpoint = Anchor { + full_offset: FullOffset(0), + bias: Bias::Left, + version: self.version.clone(), + }; + self.entries + .cursor::<()>() + .enumerate() + .filter_map(move |(ix, entry)| { + if f(&entry.value) { + endpoint.full_offset = entry.range.start; + endpoint.bias = self.start_bias; + let start = O::from_anchor(&endpoint, &content); + endpoint.full_offset = entry.range.end; + endpoint.bias = self.end_bias; + let end = O::from_anchor(&endpoint, &content); + Some((ix, start..end, &entry.value)) + } else { + None + } + }) + } } impl sum_tree::Item for AnchorRangeMultimapEntry { diff --git a/crates/language/src/lib.rs b/crates/language/src/lib.rs index bae0b0ee5e..f7e5016fc9 100644 --- a/crates/language/src/lib.rs +++ b/crates/language/src/lib.rs @@ -812,6 +812,19 @@ impl Buffer { .map(move |(_, range, diagnostic)| (range, diagnostic)) } + pub fn diagnostic_group<'a, O>( + &'a self, + group_id: usize, + ) -> impl Iterator, &Diagnostic)> + 'a + where + O: 'a + FromAnchor, + { + let content = self.content(); + self.diagnostics + .filter(content, move |diagnostic| diagnostic.group_id == group_id) + .map(move |(_, range, diagnostic)| (range, diagnostic)) + } + pub fn diagnostics_update_count(&self) -> usize { self.diagnostics_update_count } diff --git a/crates/language/src/tests.rs b/crates/language/src/tests.rs index 776d4943d9..4044c81d73 100644 --- a/crates/language/src/tests.rs +++ b/crates/language/src/tests.rs @@ -846,6 +846,57 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) { ] ); + assert_eq!( + buffer.diagnostic_group(0).collect::>(), + &[ + ( + Point::new(1, 8)..Point::new(1, 9), + &Diagnostic { + severity: DiagnosticSeverity::WARNING, + message: "error 1".to_string(), + group_id: 0 + } + ), + ( + Point::new(1, 8)..Point::new(1, 9), + &Diagnostic { + severity: DiagnosticSeverity::HINT, + message: "error 1 hint 1".to_string(), + group_id: 0 + } + ), + ] + ); + assert_eq!( + buffer.diagnostic_group(1).collect::>(), + &[ + ( + Point::new(1, 13)..Point::new(1, 15), + &Diagnostic { + severity: DiagnosticSeverity::HINT, + message: "error 2 hint 1".to_string(), + group_id: 1 + } + ), + ( + Point::new(1, 13)..Point::new(1, 15), + &Diagnostic { + severity: DiagnosticSeverity::HINT, + message: "error 2 hint 2".to_string(), + group_id: 1 + } + ), + ( + Point::new(2, 8)..Point::new(2, 17), + &Diagnostic { + severity: DiagnosticSeverity::ERROR, + message: "error 2".to_string(), + group_id: 1 + } + ) + ] + ); + buffer }); }