mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-26 20:22:30 +00:00
In a diagnostic group, mark the highest-severity diagnostic as primary
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
401b59be5c
commit
0e51365770
7 changed files with 100 additions and 63 deletions
|
@ -2205,7 +2205,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
pub fn show_next_diagnostic(&mut self, _: &ShowNextDiagnostic, cx: &mut ViewContext<Self>) {
|
||||
let selection = self.selections::<usize>(cx).last().unwrap();
|
||||
let selection = self.newest_selection(cx);
|
||||
let buffer = self.buffer.read(cx.as_ref());
|
||||
let diagnostic_group_id = dbg!(buffer
|
||||
.diagnostics_in_range::<_, usize>(selection.head()..buffer.len())
|
||||
|
|
|
@ -86,6 +86,7 @@ pub struct Diagnostic {
|
|||
pub severity: DiagnosticSeverity,
|
||||
pub message: String,
|
||||
pub group_id: usize,
|
||||
pub is_primary: bool,
|
||||
}
|
||||
|
||||
struct LanguageServerState {
|
||||
|
@ -717,68 +718,82 @@ impl Buffer {
|
|||
.peekable();
|
||||
let mut last_edit_old_end = PointUtf16::zero();
|
||||
let mut last_edit_new_end = PointUtf16::zero();
|
||||
let mut groups = HashMap::new();
|
||||
let mut group_ids_by_diagnostic_range = HashMap::new();
|
||||
let mut diagnostics_by_group_id = HashMap::new();
|
||||
let mut next_group_id = 0;
|
||||
|
||||
content.anchor_range_multimap(
|
||||
Bias::Left,
|
||||
Bias::Right,
|
||||
diagnostics.iter().filter_map(|diagnostic| {
|
||||
let mut start = diagnostic.range.start.to_point_utf16();
|
||||
let mut end = diagnostic.range.end.to_point_utf16();
|
||||
let source = diagnostic.source.as_ref();
|
||||
let code = diagnostic.code.as_ref();
|
||||
let group_id = diagnostic_ranges(&diagnostic, abs_path.as_deref())
|
||||
.find_map(|range| groups.get(&(source, code, range)))
|
||||
.copied()
|
||||
.unwrap_or_else(|| {
|
||||
let group_id = post_inc(&mut next_group_id);
|
||||
for range in diagnostic_ranges(&diagnostic, abs_path.as_deref()) {
|
||||
groups.insert((source, code, range), group_id);
|
||||
}
|
||||
group_id
|
||||
});
|
||||
|
||||
if diagnostic
|
||||
.source
|
||||
.as_ref()
|
||||
.map_or(false, |source| disk_based_sources.contains(source))
|
||||
{
|
||||
while let Some(edit) = edits_since_save.peek() {
|
||||
if edit.old.end <= start {
|
||||
last_edit_old_end = edit.old.end;
|
||||
last_edit_new_end = edit.new.end;
|
||||
edits_since_save.next();
|
||||
} else if edit.old.start <= end && edit.old.end >= start {
|
||||
return None;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
'outer: for diagnostic in &diagnostics {
|
||||
let mut start = diagnostic.range.start.to_point_utf16();
|
||||
let mut end = diagnostic.range.end.to_point_utf16();
|
||||
let source = diagnostic.source.as_ref();
|
||||
let code = diagnostic.code.as_ref();
|
||||
let group_id = diagnostic_ranges(&diagnostic, abs_path.as_deref())
|
||||
.find_map(|range| group_ids_by_diagnostic_range.get(&(source, code, range)))
|
||||
.copied()
|
||||
.unwrap_or_else(|| {
|
||||
let group_id = post_inc(&mut next_group_id);
|
||||
for range in diagnostic_ranges(&diagnostic, abs_path.as_deref()) {
|
||||
group_ids_by_diagnostic_range.insert((source, code, range), group_id);
|
||||
}
|
||||
group_id
|
||||
});
|
||||
|
||||
start = last_edit_new_end + (start - last_edit_old_end);
|
||||
end = last_edit_new_end + (end - last_edit_old_end);
|
||||
}
|
||||
|
||||
let mut range = content.clip_point_utf16(start, Bias::Left)
|
||||
..content.clip_point_utf16(end, Bias::Right);
|
||||
if range.start == range.end {
|
||||
range.end.column += 1;
|
||||
range.end = content.clip_point_utf16(range.end, Bias::Right);
|
||||
if range.start == range.end && range.end.column > 0 {
|
||||
range.start.column -= 1;
|
||||
range.start = content.clip_point_utf16(range.start, Bias::Left);
|
||||
if diagnostic
|
||||
.source
|
||||
.as_ref()
|
||||
.map_or(false, |source| disk_based_sources.contains(source))
|
||||
{
|
||||
while let Some(edit) = edits_since_save.peek() {
|
||||
if edit.old.end <= start {
|
||||
last_edit_old_end = edit.old.end;
|
||||
last_edit_new_end = edit.new.end;
|
||||
edits_since_save.next();
|
||||
} else if edit.old.start <= end && edit.old.end >= start {
|
||||
continue 'outer;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Some((
|
||||
|
||||
start = last_edit_new_end + (start - last_edit_old_end);
|
||||
end = last_edit_new_end + (end - last_edit_old_end);
|
||||
}
|
||||
|
||||
let mut range = content.clip_point_utf16(start, Bias::Left)
|
||||
..content.clip_point_utf16(end, Bias::Right);
|
||||
if range.start == range.end {
|
||||
range.end.column += 1;
|
||||
range.end = content.clip_point_utf16(range.end, Bias::Right);
|
||||
if range.start == range.end && range.end.column > 0 {
|
||||
range.start.column -= 1;
|
||||
range.start = content.clip_point_utf16(range.start, Bias::Left);
|
||||
}
|
||||
}
|
||||
|
||||
diagnostics_by_group_id
|
||||
.entry(group_id)
|
||||
.or_insert(Vec::new())
|
||||
.push((
|
||||
range,
|
||||
Diagnostic {
|
||||
severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
|
||||
message: diagnostic.message.clone(),
|
||||
group_id,
|
||||
is_primary: false,
|
||||
},
|
||||
))
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
content.anchor_range_multimap(
|
||||
Bias::Left,
|
||||
Bias::Right,
|
||||
diagnostics_by_group_id
|
||||
.into_values()
|
||||
.flat_map(|mut diagnostics| {
|
||||
let primary_diagnostic =
|
||||
diagnostics.iter_mut().min_by_key(|d| d.1.severity).unwrap();
|
||||
primary_diagnostic.1.is_primary = true;
|
||||
diagnostics
|
||||
}),
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@ pub fn serialize_diagnostics(map: &AnchorRangeMultimap<Diagnostic>) -> proto::Di
|
|||
_ => proto::diagnostic::Severity::None,
|
||||
} as i32,
|
||||
group_id: diagnostic.group_id as u64,
|
||||
is_primary: diagnostic.is_primary,
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
|
@ -310,6 +311,7 @@ pub fn deserialize_diagnostics(message: proto::DiagnosticSet) -> AnchorRangeMult
|
|||
},
|
||||
message: diagnostic.message,
|
||||
group_id: diagnostic.group_id as usize,
|
||||
is_primary: diagnostic.is_primary,
|
||||
},
|
||||
))
|
||||
}),
|
||||
|
|
|
@ -484,6 +484,7 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
severity: DiagnosticSeverity::ERROR,
|
||||
message: "undefined variable 'BB'".to_string(),
|
||||
group_id: 1,
|
||||
is_primary: true,
|
||||
},
|
||||
),
|
||||
(
|
||||
|
@ -492,6 +493,7 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
severity: DiagnosticSeverity::ERROR,
|
||||
message: "undefined variable 'CCC'".to_string(),
|
||||
group_id: 2,
|
||||
is_primary: true,
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -549,6 +551,7 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
severity: DiagnosticSeverity::WARNING,
|
||||
message: "unreachable statement".to_string(),
|
||||
group_id: 1,
|
||||
is_primary: true,
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -557,6 +560,7 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
severity: DiagnosticSeverity::ERROR,
|
||||
message: "undefined variable 'A'".to_string(),
|
||||
group_id: 0,
|
||||
is_primary: true,
|
||||
},
|
||||
)
|
||||
]
|
||||
|
@ -626,6 +630,7 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
severity: DiagnosticSeverity::ERROR,
|
||||
message: "undefined variable 'A'".to_string(),
|
||||
group_id: 0,
|
||||
is_primary: true,
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -634,6 +639,7 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
severity: DiagnosticSeverity::ERROR,
|
||||
message: "undefined variable 'BB'".to_string(),
|
||||
group_id: 1,
|
||||
is_primary: true,
|
||||
},
|
||||
)
|
||||
]
|
||||
|
@ -808,7 +814,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::WARNING,
|
||||
message: "error 1".to_string(),
|
||||
group_id: 0
|
||||
group_id: 0,
|
||||
is_primary: true,
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -816,7 +823,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::HINT,
|
||||
message: "error 1 hint 1".to_string(),
|
||||
group_id: 0
|
||||
group_id: 0,
|
||||
is_primary: false,
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -824,7 +832,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::HINT,
|
||||
message: "error 2 hint 1".to_string(),
|
||||
group_id: 1
|
||||
group_id: 1,
|
||||
is_primary: false,
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -832,7 +841,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::HINT,
|
||||
message: "error 2 hint 2".to_string(),
|
||||
group_id: 1
|
||||
group_id: 1,
|
||||
is_primary: false,
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -840,7 +850,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::ERROR,
|
||||
message: "error 2".to_string(),
|
||||
group_id: 1
|
||||
group_id: 1,
|
||||
is_primary: true,
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -854,7 +865,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::WARNING,
|
||||
message: "error 1".to_string(),
|
||||
group_id: 0
|
||||
group_id: 0,
|
||||
is_primary: true,
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -862,7 +874,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::HINT,
|
||||
message: "error 1 hint 1".to_string(),
|
||||
group_id: 0
|
||||
group_id: 0,
|
||||
is_primary: false,
|
||||
}
|
||||
),
|
||||
]
|
||||
|
@ -875,7 +888,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::HINT,
|
||||
message: "error 2 hint 1".to_string(),
|
||||
group_id: 1
|
||||
group_id: 1,
|
||||
is_primary: false,
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -883,7 +897,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::HINT,
|
||||
message: "error 2 hint 2".to_string(),
|
||||
group_id: 1
|
||||
group_id: 1,
|
||||
is_primary: false,
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -891,7 +906,8 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||
&Diagnostic {
|
||||
severity: DiagnosticSeverity::ERROR,
|
||||
message: "error 2".to_string(),
|
||||
group_id: 1
|
||||
group_id: 1,
|
||||
is_primary: true,
|
||||
}
|
||||
)
|
||||
]
|
||||
|
|
|
@ -3635,6 +3635,7 @@ mod tests {
|
|||
severity: lsp::DiagnosticSeverity::ERROR,
|
||||
message: "undefined variable 'A'".to_string(),
|
||||
group_id: 0,
|
||||
is_primary: true
|
||||
}
|
||||
)]
|
||||
)
|
||||
|
|
|
@ -257,6 +257,7 @@ message Diagnostic {
|
|||
Severity severity = 3;
|
||||
string message = 4;
|
||||
uint64 group_id = 5;
|
||||
bool is_primary = 6;
|
||||
enum Severity {
|
||||
None = 0;
|
||||
Error = 1;
|
||||
|
|
|
@ -1716,6 +1716,7 @@ mod tests {
|
|||
group_id: 0,
|
||||
message: "message 1".to_string(),
|
||||
severity: lsp::DiagnosticSeverity::ERROR,
|
||||
is_primary: true
|
||||
}
|
||||
),
|
||||
(
|
||||
|
@ -1723,7 +1724,8 @@ mod tests {
|
|||
&Diagnostic {
|
||||
group_id: 1,
|
||||
severity: lsp::DiagnosticSeverity::WARNING,
|
||||
message: "message 2".to_string()
|
||||
message: "message 2".to_string(),
|
||||
is_primary: true
|
||||
}
|
||||
)
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue