aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/application.rs
diff options
context:
space:
mode:
authorPhilipp Mildenberger2024-01-09 01:01:04 +0000
committerGitHub2024-01-09 01:01:04 +0000
commit41ca46cf8ca65dbd98df7e038fc12a272f0c9e2a (patch)
treee222eececda605353414b18921de63a35d8acd1c /helix-term/src/application.rs
parent46ecc102ba6d6c2e6e707b551e24faa240752c87 (diff)
Initialize diagnostics when opening a document (#8873)
Diffstat (limited to 'helix-term/src/application.rs')
-rw-r--r--helix-term/src/application.rs160
1 files changed, 40 insertions, 120 deletions
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index 3abe9cae..4eda8097 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -1,14 +1,8 @@
use arc_swap::{access::Map, ArcSwap};
use futures_util::Stream;
-use helix_core::{
- chars::char_is_word,
- diagnostic::{DiagnosticTag, NumberOrString},
- path::get_relative_path,
- pos_at_coords, syntax, Selection,
-};
+use helix_core::{path::get_relative_path, pos_at_coords, syntax, Selection};
use helix_lsp::{
lsp::{self, notification::Notification},
- util::lsp_pos_to_pos,
LspProgressMap,
};
use helix_view::{
@@ -392,6 +386,12 @@ impl Application {
self.editor.syn_loader = self.syn_loader.clone();
for document in self.editor.documents.values_mut() {
document.detect_language(self.syn_loader.clone());
+ let diagnostics = Editor::doc_diagnostics(
+ &self.editor.language_servers,
+ &self.editor.diagnostics,
+ document,
+ );
+ document.replace_diagnostics(diagnostics, &[], None);
}
Ok(())
@@ -567,6 +567,14 @@ impl Application {
let id = doc.id();
doc.detect_language(loader);
self.editor.refresh_language_servers(id);
+ // and again a borrow checker workaround...
+ let doc = doc_mut!(self.editor, &doc_save_event.doc_id);
+ let diagnostics = Editor::doc_diagnostics(
+ &self.editor.language_servers,
+ &self.editor.diagnostics,
+ doc,
+ );
+ doc.replace_diagnostics(diagnostics, &[], None);
}
// TODO: fix being overwritten by lsp
@@ -731,7 +739,6 @@ impl Application {
log::error!("Discarding publishDiagnostic notification sent by an uninitialized server: {}", language_server.name());
return;
}
- let offset_encoding = language_server.offset_encoding();
// have to inline the function because of borrow checking...
let doc = self.editor.documents.values_mut()
.find(|doc| doc.path().map(|p| p == &path).unwrap_or(false))
@@ -745,11 +752,10 @@ impl Application {
true
});
- if let Some(doc) = doc {
+ let mut unchanged_diag_sources = Vec::new();
+ if let Some(doc) = &doc {
let lang_conf = doc.language.clone();
- let text = doc.text().clone();
- let mut unchaged_diag_sources_ = Vec::new();
if let Some(lang_conf) = &lang_conf {
if let Some(old_diagnostics) =
self.editor.diagnostics.get(&params.uri)
@@ -774,118 +780,11 @@ impl Application {
})
.map(|(d, _)| d);
if new_diagnostics.eq(old_diagnostics) {
- unchaged_diag_sources_.push(source.clone())
+ unchanged_diag_sources.push(source.clone())
}
}
}
}
-
- let unchaged_diag_sources = &unchaged_diag_sources_;
- let diagnostics =
- params.diagnostics.iter().filter_map(move |diagnostic| {
- use helix_core::diagnostic::{Diagnostic, Range, Severity::*};
- use lsp::DiagnosticSeverity;
-
- if diagnostic.source.as_ref().map_or(false, |source| {
- unchaged_diag_sources.contains(source)
- }) {
- return None;
- }
-
- // TODO: convert inside server
- let start = if let Some(start) = lsp_pos_to_pos(
- &text,
- diagnostic.range.start,
- offset_encoding,
- ) {
- start
- } else {
- log::warn!("lsp position out of bounds - {:?}", diagnostic);
- return None;
- };
-
- let end = if let Some(end) =
- lsp_pos_to_pos(&text, diagnostic.range.end, offset_encoding)
- {
- end
- } else {
- log::warn!("lsp position out of bounds - {:?}", diagnostic);
- return None;
- };
- let severity =
- diagnostic.severity.map(|severity| match severity {
- DiagnosticSeverity::ERROR => Error,
- DiagnosticSeverity::WARNING => Warning,
- DiagnosticSeverity::INFORMATION => Info,
- DiagnosticSeverity::HINT => Hint,
- severity => unreachable!(
- "unrecognized diagnostic severity: {:?}",
- severity
- ),
- });
-
- if let Some(lang_conf) = &lang_conf {
- if let Some(severity) = severity {
- if severity < lang_conf.diagnostic_severity {
- return None;
- }
- }
- };
-
- let code = match diagnostic.code.clone() {
- Some(x) => match x {
- lsp::NumberOrString::Number(x) => {
- Some(NumberOrString::Number(x))
- }
- lsp::NumberOrString::String(x) => {
- Some(NumberOrString::String(x))
- }
- },
- None => None,
- };
-
- let tags = if let Some(tags) = &diagnostic.tags {
- let new_tags = tags
- .iter()
- .filter_map(|tag| match *tag {
- lsp::DiagnosticTag::DEPRECATED => {
- Some(DiagnosticTag::Deprecated)
- }
- lsp::DiagnosticTag::UNNECESSARY => {
- Some(DiagnosticTag::Unnecessary)
- }
- _ => None,
- })
- .collect();
-
- new_tags
- } else {
- Vec::new()
- };
-
- let ends_at_word = start != end
- && end != 0
- && text.get_char(end - 1).map_or(false, char_is_word);
- let starts_at_word = start != end
- && text.get_char(start).map_or(false, char_is_word);
-
- Some(Diagnostic {
- range: Range { start, end },
- ends_at_word,
- starts_at_word,
- zero_width: start == end,
- line: diagnostic.range.start.line as usize,
- message: diagnostic.message.clone(),
- severity,
- code,
- tags,
- source: diagnostic.source.clone(),
- data: diagnostic.data.clone(),
- language_server_id: server_id,
- })
- });
-
- doc.replace_diagnostics(diagnostics, unchaged_diag_sources, server_id);
}
let diagnostics = params.diagnostics.into_iter().map(|d| (d, server_id));
@@ -910,6 +809,27 @@ impl Application {
diagnostics.sort_unstable_by_key(|(d, server_id)| {
(d.severity, d.range.start, *server_id)
});
+
+ if let Some(doc) = doc {
+ let diagnostic_of_language_server_and_not_in_unchanged_sources =
+ |diagnostic: &lsp::Diagnostic, ls_id| {
+ ls_id == server_id
+ && diagnostic.source.as_ref().map_or(true, |source| {
+ !unchanged_diag_sources.contains(source)
+ })
+ };
+ let diagnostics = Editor::doc_diagnostics_with_filter(
+ &self.editor.language_servers,
+ &self.editor.diagnostics,
+ doc,
+ diagnostic_of_language_server_and_not_in_unchanged_sources,
+ );
+ doc.replace_diagnostics(
+ diagnostics,
+ &unchanged_diag_sources,
+ Some(server_id),
+ );
+ }
}
Notification::ShowMessage(params) => {
log::warn!("unhandled window/showMessage: {:?}", params);
@@ -1017,7 +937,7 @@ impl Application {
// Clear any diagnostics for documents with this server open.
for doc in self.editor.documents_mut() {
- doc.clear_diagnostics(server_id);
+ doc.clear_diagnostics(Some(server_id));
}
// Remove the language server from the registry.