Fix panic on diagnostic hover (#22693)

In #22620 `diagnostic_group` was modified to return results for
multibuffers, but was returning singleton buffer points. `hover_popover`
uses it to find the jump target for clicking the popup - which doesn't
seem to be working right now but that's a separate issue. Now that
`diagnostic_group` is returning values in multibuffers converting these
to anchors was crashing.

Also resolves a potential bug - if folding in multibuffers was supported
then "Go To Diagnostics" would not properly skip diagnostics from folded
regions.

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2025-01-05 19:31:02 -07:00 committed by GitHub
parent 94ee2e1811
commit 570e6c80a8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 22 deletions

View file

@ -10336,16 +10336,18 @@ impl Editor {
let mut primary_message = None; let mut primary_message = None;
let mut group_end = Point::zero(); let mut group_end = Point::zero();
let diagnostic_group = buffer let diagnostic_group = buffer
.diagnostic_group::<MultiBufferPoint>(group_id) .diagnostic_group(group_id)
.filter_map(|entry| { .filter_map(|entry| {
if snapshot.is_line_folded(MultiBufferRow(entry.range.start.row)) let start = entry.range.start.to_point(&buffer);
&& (entry.range.start.row == entry.range.end.row let end = entry.range.end.to_point(&buffer);
|| snapshot.is_line_folded(MultiBufferRow(entry.range.end.row))) if snapshot.is_line_folded(MultiBufferRow(start.row))
&& (start.row == end.row
|| snapshot.is_line_folded(MultiBufferRow(end.row)))
{ {
return None; return None;
} }
if entry.range.end > group_end { if end > group_end {
group_end = entry.range.end; group_end = end;
} }
if entry.diagnostic.is_primary { if entry.diagnostic.is_primary {
primary_range = Some(entry.range.clone()); primary_range = Some(entry.range.clone());
@ -10356,8 +10358,6 @@ impl Editor {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let primary_range = primary_range?; let primary_range = primary_range?;
let primary_message = primary_message?; let primary_message = primary_message?;
let primary_range =
buffer.anchor_after(primary_range.start)..buffer.anchor_before(primary_range.end);
let blocks = display_map let blocks = display_map
.insert_blocks( .insert_blocks(

View file

@ -3,7 +3,7 @@ use crate::{
hover_links::{InlayHighlight, RangeInEditor}, hover_links::{InlayHighlight, RangeInEditor},
scroll::ScrollAmount, scroll::ScrollAmount,
Anchor, AnchorRangeExt, DisplayPoint, DisplayRow, Editor, EditorSettings, EditorSnapshot, Anchor, AnchorRangeExt, DisplayPoint, DisplayRow, Editor, EditorSettings, EditorSnapshot,
Hover, RangeToAnchorExt, Hover,
}; };
use gpui::{ use gpui::{
div, px, AnyElement, AsyncWindowContext, FontWeight, Hsla, InteractiveElement, IntoElement, div, px, AnyElement, AsyncWindowContext, FontWeight, Hsla, InteractiveElement, IntoElement,
@ -277,12 +277,8 @@ fn show_hover(
let primary_diagnostic = local_diagnostic.as_ref().and_then(|local_diagnostic| { let primary_diagnostic = local_diagnostic.as_ref().and_then(|local_diagnostic| {
snapshot snapshot
.buffer_snapshot .buffer_snapshot
.diagnostic_group::<usize>(local_diagnostic.diagnostic.group_id) .diagnostic_group(local_diagnostic.diagnostic.group_id)
.find(|diagnostic| diagnostic.diagnostic.is_primary) .find(|diagnostic| diagnostic.diagnostic.is_primary)
.map(|entry| DiagnosticEntry {
diagnostic: entry.diagnostic,
range: entry.range.to_anchors(&snapshot.buffer_snapshot),
})
}); });
if let Some(invisible) = snapshot if let Some(invisible) = snapshot
.buffer_snapshot .buffer_snapshot

View file

@ -3871,15 +3871,19 @@ impl MultiBufferSnapshot {
.any(|excerpt| excerpt.buffer.has_diagnostics()) .any(|excerpt| excerpt.buffer.has_diagnostics())
} }
pub fn diagnostic_group<'a, O>( pub fn diagnostic_group(
&'a self, &self,
group_id: usize, group_id: usize,
) -> impl Iterator<Item = DiagnosticEntry<O>> + 'a ) -> impl Iterator<Item = DiagnosticEntry<Anchor>> + '_ {
where self.all_excerpts().flat_map(move |excerpt| {
O: text::FromAnchor + 'a, excerpt.buffer().diagnostic_group(group_id).map(
{ move |DiagnosticEntry { diagnostic, range }| DiagnosticEntry {
self.all_excerpts() diagnostic,
.flat_map(move |excerpt| excerpt.buffer().diagnostic_group(group_id)) range: self.anchor_in_excerpt(excerpt.id(), range.start).unwrap()
..self.anchor_in_excerpt(excerpt.id(), range.end).unwrap(),
},
)
})
} }
pub fn diagnostics_in_range<'a, T>( pub fn diagnostics_in_range<'a, T>(