Sort LSP diagnostics by (start, end)

This commit is contained in:
Antonio Scandurra 2021-10-28 11:35:33 +02:00
parent fcb217b9e8
commit ac76706aa7

View file

@ -647,7 +647,7 @@ impl Buffer {
pub fn update_diagnostics( pub fn update_diagnostics(
&mut self, &mut self,
version: Option<i32>, version: Option<i32>,
diagnostics: Vec<lsp::Diagnostic>, mut diagnostics: Vec<lsp::Diagnostic>,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Result<()> { ) -> Result<()> {
let version = version.map(|version| version as usize); let version = version.map(|version| version as usize);
@ -669,46 +669,50 @@ impl Buffer {
.and_then(|language| language.disk_based_diagnostic_sources()) .and_then(|language| language.disk_based_diagnostic_sources())
.unwrap_or(&empty_set); .unwrap_or(&empty_set);
let mut edits_since_save = self.text.edits_since(self.saved_version.clone()).peekable(); diagnostics.sort_unstable_by_key(|d| (d.range.start, d.range.end));
let mut last_edit_old_end = Point::zero(); self.diagnostics = {
let mut last_edit_new_end = Point::zero(); let mut edits_since_save = content.edits_since(self.saved_version.clone()).peekable();
let mut last_edit_old_end = Point::zero();
let mut last_edit_new_end = Point::zero();
self.diagnostics = content.anchor_range_multimap( content.anchor_range_multimap(
Bias::Left, Bias::Left,
Bias::Right, Bias::Right,
diagnostics.into_iter().filter_map(|diagnostic| { diagnostics.into_iter().filter_map(|diagnostic| {
// TODO: Use UTF-16 positions. // TODO: Use UTF-16 positions.
let mut start = Point::new( let mut start = Point::new(
diagnostic.range.start.line, diagnostic.range.start.line,
diagnostic.range.start.character, diagnostic.range.start.character,
); );
let mut end = Point::new(diagnostic.range.end.line, diagnostic.range.end.character); let mut end =
let severity = diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR); Point::new(diagnostic.range.end.line, diagnostic.range.end.character);
let severity = diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR);
if diagnostic if diagnostic
.source .source
.as_ref() .as_ref()
.map_or(false, |source| disk_based_sources.contains(source)) .map_or(false, |source| disk_based_sources.contains(source))
{ {
while let Some(edit) = edits_since_save.peek() { while let Some(edit) = edits_since_save.peek() {
if edit.old_lines.end <= start { if edit.old_lines.end <= start {
last_edit_old_end = edit.old_lines.end; last_edit_old_end = edit.old_lines.end;
last_edit_new_end = edit.new_lines.end; last_edit_new_end = edit.new_lines.end;
edits_since_save.next(); edits_since_save.next();
} else if edit.old_lines.start <= end && edit.old_lines.end >= start { } else if edit.old_lines.start <= end && edit.old_lines.end >= start {
return None; return None;
} else { } else {
break; break;
}
} }
start = last_edit_new_end + (start - last_edit_old_end);
end = last_edit_new_end + (end - last_edit_old_end);
} }
start = last_edit_new_end + (start - last_edit_old_end); Some((start..end, (severity, diagnostic.message)))
end = last_edit_new_end + (end - last_edit_old_end); }),
} )
};
Some((start..end, (severity, diagnostic.message)))
}),
);
if let Some(version) = version { if let Some(version) = version {
let language_server = self.language_server.as_mut().unwrap(); let language_server = self.language_server.as_mut().unwrap();