Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize diagnostics when opening a document #8873

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion helix-core/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1795,7 +1795,6 @@ impl HighlightConfiguration {
let mut best_index = None;
let mut best_match_len = 0;
for (i, recognized_name) in recognized_names.iter().enumerate() {
let recognized_name = recognized_name;
let mut len = 0;
let mut matches = true;
for (i, part) in recognized_name.split('.').enumerate() {
Expand Down
143 changes: 23 additions & 120 deletions helix-term/src/application.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand Down Expand Up @@ -731,7 +725,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))
Expand All @@ -745,11 +738,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)
Expand All @@ -774,118 +766,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));
Expand All @@ -910,6 +795,24 @@ impl Application {
diagnostics.sort_unstable_by_key(|(d, server_id)| {
(d.severity, d.range.start, *server_id)
});

if let Some(doc) = doc {
doc.replace_diagnostics(
Editor::doc_diagnostics_with_filter(
&self.editor.language_servers,
&self.editor.diagnostics,
doc,
|diagnostic, ls_id| {
ls_id == server_id
&& diagnostic.source.as_ref().map_or(true, |source| {
!unchanged_diag_sources.contains(source)
})
},
),
pascalkuthe marked this conversation as resolved.
Show resolved Hide resolved
&unchanged_diag_sources,
Some(server_id),
);
}
}
Notification::ShowMessage(params) => {
log::warn!("unhandled window/showMessage: {:?}", params);
Expand Down Expand Up @@ -1017,7 +920,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.
Expand Down
26 changes: 17 additions & 9 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3350,7 +3350,7 @@ fn exit_select_mode(cx: &mut Context) {

fn goto_first_diag(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
let selection = match doc.shown_diagnostics().next() {
let selection = match doc.diagnostics().first() {
Some(diag) => Selection::single(diag.range.start, diag.range.end),
None => return,
};
Expand All @@ -3359,7 +3359,7 @@ fn goto_first_diag(cx: &mut Context) {

fn goto_last_diag(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
let selection = match doc.shown_diagnostics().last() {
let selection = match doc.diagnostics().last() {
Some(diag) => Selection::single(diag.range.start, diag.range.end),
None => return,
};
Expand All @@ -3375,9 +3375,10 @@ fn goto_next_diag(cx: &mut Context) {
.cursor(doc.text().slice(..));

let diag = doc
.shown_diagnostics()
.diagnostics()
.iter()
.find(|diag| diag.range.start > cursor_pos)
.or_else(|| doc.shown_diagnostics().next());
.or_else(|| doc.diagnostics().first());

let selection = match diag {
Some(diag) => Selection::single(diag.range.start, diag.range.end),
Expand All @@ -3395,10 +3396,11 @@ fn goto_prev_diag(cx: &mut Context) {
.cursor(doc.text().slice(..));

let diag = doc
.shown_diagnostics()
.diagnostics()
.iter()
.rev()
.find(|diag| diag.range.start < cursor_pos)
.or_else(|| doc.shown_diagnostics().last());
.or_else(|| doc.diagnostics().last());

let selection = match diag {
// NOTE: the selection is reversed because we're jumping to the
Expand Down Expand Up @@ -4185,9 +4187,13 @@ fn replace_with_yanked(cx: &mut Context) {
}

fn replace_with_yanked_impl(editor: &mut Editor, register: char, count: usize) {
let Some(values) = editor.registers
let Some(values) = editor
.registers
.read(register, editor)
.filter(|values| values.len() > 0) else { return };
.filter(|values| values.len() > 0)
else {
return;
};
let values: Vec<_> = values.map(|value| value.to_string()).collect();

let (view, doc) = current!(editor);
Expand Down Expand Up @@ -4224,7 +4230,9 @@ fn replace_selections_with_primary_clipboard(cx: &mut Context) {
}

fn paste(editor: &mut Editor, register: char, pos: Paste, count: usize) {
let Some(values) = editor.registers.read(register, editor) else { return };
let Some(values) = editor.registers.read(register, editor) else {
return;
};
let values: Vec<_> = values.map(|value| value.to_string()).collect();

let (view, doc) = current!(editor);
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1502,7 +1502,7 @@ fn lsp_stop(

for doc in cx.editor.documents_mut() {
if let Some(client) = doc.remove_language_server_by_name(ls_name) {
doc.clear_diagnostics(client.id());
doc.clear_diagnostics(Some(client.id()));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ impl EditorView {
let mut warning_vec = Vec::new();
let mut error_vec = Vec::new();

for diagnostic in doc.shown_diagnostics() {
for diagnostic in doc.diagnostics() {
// Separate diagnostics into different Vecs by severity.
let (vec, scope) = match diagnostic.severity {
Some(Severity::Info) => (&mut info_vec, info),
Expand Down Expand Up @@ -684,7 +684,7 @@ impl EditorView {
.primary()
.cursor(doc.text().slice(..));

let diagnostics = doc.shown_diagnostics().filter(|diagnostic| {
let diagnostics = doc.diagnostics().iter().filter(|diagnostic| {
diagnostic.range.start <= cursor && diagnostic.range.end >= cursor
});

Expand Down
13 changes: 10 additions & 3 deletions helix-term/src/ui/picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,16 +480,23 @@ impl<T: Item + 'static> Picker<T> {
.find::<Overlay<DynamicPicker<T>>>()
.map(|overlay| &mut overlay.content.file_picker),
};
let Some(picker) = picker
else {
let Some(picker) = picker else {
log::info!("picker closed before syntax highlighting finished");
return;
};
// Try to find a document in the cache
let doc = match current_file {
PathOrId::Id(doc_id) => doc_mut!(editor, &doc_id),
PathOrId::Path(path) => match picker.preview_cache.get_mut(&path) {
Some(CachedPreview::Document(ref mut doc)) => doc,
Some(CachedPreview::Document(ref mut doc)) => {
let diagnostics = Editor::doc_diagnostics(
&editor.language_servers,
&editor.diagnostics,
doc,
);
doc.replace_diagnostics(diagnostics, &[], None);
doc
}
_ => return,
},
};
Expand Down
3 changes: 2 additions & 1 deletion helix-term/src/ui/statusline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ where
{
let (warnings, errors) = context
.doc
.shown_diagnostics()
.diagnostics()
.iter()
.fold((0, 0), |mut counts, diag| {
use helix_core::diagnostic::Severity;
match diag.severity {
Expand Down
Loading
Loading