Skip to content

Commit f4d6635

Browse files
committed
refactor: move add_diagnostics to separate method
1 parent 63e6c2d commit f4d6635

File tree

3 files changed

+73
-91
lines changed

3 files changed

+73
-91
lines changed

helix-term/src/application.rs

+2-27
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use log::{debug, error, warn};
3232
#[cfg(not(feature = "integration"))]
3333
use std::io::stdout;
3434
use std::{
35-
collections::btree_map::Entry,
3635
io::stdin,
3736
path::Path,
3837
sync::{atomic, Arc},
@@ -764,32 +763,8 @@ impl Application {
764763
doc.replace_diagnostics(diagnostics, server_id);
765764
}
766765

767-
let mut diagnostics = params
768-
.diagnostics
769-
.into_iter()
770-
.map(|d| (d, server_id))
771-
.collect();
772-
773-
// Insert the original lsp::Diagnostics here because we may have no open document
774-
// for diagnosic message and so we can't calculate the exact position.
775-
// When using them later in the diagnostics picker, we calculate them on-demand.
776-
match self.editor.diagnostics.entry(params.uri) {
777-
Entry::Occupied(o) => {
778-
let current_diagnostics = o.into_mut();
779-
// there may entries of other language servers, which is why we can't overwrite the whole entry
780-
current_diagnostics.retain(|(_, lsp_id)| *lsp_id != server_id);
781-
current_diagnostics.append(&mut diagnostics);
782-
// Sort diagnostics first by severity and then by line numbers.
783-
// Note: The `lsp::DiagnosticSeverity` enum is already defined in decreasing order
784-
current_diagnostics
785-
.sort_unstable_by_key(|(d, _)| (d.severity, d.range.start));
786-
}
787-
Entry::Vacant(v) => {
788-
diagnostics
789-
.sort_unstable_by_key(|(d, _)| (d.severity, d.range.start));
790-
v.insert(diagnostics);
791-
}
792-
};
766+
self.editor
767+
.add_diagnostics(params.diagnostics, params.uri, server_id);
793768
}
794769
Notification::ShowMessage(params) => {
795770
log::warn!("unhandled window/showMessage: {:?}", params);

helix-term/src/commands/lsp.rs

+45-63
Original file line numberDiff line numberDiff line change
@@ -1497,53 +1497,7 @@ pub fn select_references_to_symbol_under_cursor(cx: &mut Context) {
14971497
);
14981498
}
14991499

1500-
pub fn pull_diagnostic_for_current_doc(editor: &mut Editor, jobs: &mut crate::job::Jobs) {
1501-
fn parse_diagnostic(
1502-
doc: &mut Document,
1503-
offset_encoding: OffsetEncoding,
1504-
server_id: usize,
1505-
report: Vec<lsp::Diagnostic>,
1506-
result_id: Option<String>,
1507-
) {
1508-
let diagnostics = lsp_diagnostic_to_diagnostic(
1509-
&report,
1510-
doc.text(),
1511-
offset_encoding,
1512-
doc.language_config(),
1513-
server_id,
1514-
);
1515-
doc.previous_diagnostic_id = result_id;
1516-
doc.replace_diagnostics(diagnostics, server_id);
1517-
}
1518-
1519-
fn handle_document_diagnostic_report_kind(
1520-
editor: &mut Editor,
1521-
offset_encoding: OffsetEncoding,
1522-
server_id: usize,
1523-
report: Option<HashMap<lsp::Url, lsp::DocumentDiagnosticReportKind>>,
1524-
) {
1525-
for (url, report) in report.into_iter().flatten() {
1526-
let Some(doc) = editor.document_by_path_mut(url.path())
1527-
else {
1528-
continue;
1529-
};
1530-
match report {
1531-
lsp::DocumentDiagnosticReportKind::Full(report) => {
1532-
parse_diagnostic(
1533-
doc,
1534-
offset_encoding,
1535-
server_id,
1536-
report.items,
1537-
report.result_id,
1538-
);
1539-
}
1540-
lsp::DocumentDiagnosticReportKind::Unchanged(report) => {
1541-
doc.previous_diagnostic_id = Some(report.result_id);
1542-
}
1543-
}
1544-
}
1545-
}
1546-
1500+
pub fn pull_diagnostic_for_current_doc(editor: &Editor, jobs: &mut crate::job::Jobs) {
15471501
let doc = doc!(editor);
15481502
let Some(language_server) = doc
15491503
.language_servers_with_feature(LanguageServerFeature::PullDiagnostics)
@@ -1584,35 +1538,63 @@ pub fn pull_diagnostic_for_current_doc(editor: &mut Editor, jobs: &mut crate::jo
15841538
let offset_encoding = language_server.offset_encoding();
15851539
let server_id = language_server.id();
15861540

1541+
let parse_diagnostic = |editor: &mut Editor,
1542+
path,
1543+
report: Vec<lsp::Diagnostic>,
1544+
result_id: Option<String>| {
1545+
if let Some(doc) = editor.document_by_path_mut(&path) {
1546+
let diagnostics = lsp_diagnostic_to_diagnostic(
1547+
&report,
1548+
doc.text(),
1549+
offset_encoding,
1550+
doc.language_config(),
1551+
server_id,
1552+
);
1553+
doc.previous_diagnostic_id = result_id;
1554+
doc.replace_diagnostics(diagnostics, server_id);
1555+
}
1556+
let url = lsp::Url::from_file_path(&path).unwrap();
1557+
editor.add_diagnostics(report, url, server_id);
1558+
};
1559+
1560+
let handle_document_diagnostic_report_kind = |editor: &mut Editor,
1561+
report: Option<
1562+
HashMap<lsp::Url, lsp::DocumentDiagnosticReportKind>,
1563+
>| {
1564+
for (url, report) in report.into_iter().flatten() {
1565+
match report {
1566+
lsp::DocumentDiagnosticReportKind::Full(report) => {
1567+
let path = url.to_file_path().unwrap();
1568+
parse_diagnostic(editor, path, report.items, report.result_id);
1569+
}
1570+
lsp::DocumentDiagnosticReportKind::Unchanged(report) => {
1571+
let Some(doc) = editor.document_by_path_mut(url.path()) else {
1572+
return;
1573+
};
1574+
doc.previous_diagnostic_id = Some(report.result_id);
1575+
}
1576+
}
1577+
}
1578+
};
1579+
15871580
if let Some(response) = response {
15881581
match response {
15891582
lsp::DocumentDiagnosticReport::Full(report) => {
15901583
// Original file diagnostic
15911584
parse_diagnostic(
1592-
doc,
1593-
offset_encoding,
1594-
server_id,
1585+
editor,
1586+
original_path,
15951587
report.full_document_diagnostic_report.items,
15961588
report.full_document_diagnostic_report.result_id,
15971589
);
15981590

1599-
// Related file diagnostic
1600-
handle_document_diagnostic_report_kind(
1601-
editor,
1602-
offset_encoding,
1603-
server_id,
1604-
report.related_documents,
1605-
);
1591+
// Related files diagnostic
1592+
handle_document_diagnostic_report_kind(editor, report.related_documents);
16061593
}
16071594
lsp::DocumentDiagnosticReport::Unchanged(report) => {
16081595
doc.previous_diagnostic_id =
16091596
Some(report.unchanged_document_diagnostic_report.result_id);
1610-
handle_document_diagnostic_report_kind(
1611-
editor,
1612-
offset_encoding,
1613-
server_id,
1614-
report.related_documents,
1615-
);
1597+
handle_document_diagnostic_report_kind(editor, report.related_documents);
16161598
}
16171599
}
16181600
}

helix-view/src/editor.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use tokio_stream::wrappers::UnboundedReceiverStream;
2121
use std::{
2222
borrow::Cow,
2323
cell::Cell,
24-
collections::{BTreeMap, HashMap},
24+
collections::{btree_map::Entry, BTreeMap, HashMap},
2525
io::stdin,
2626
num::NonZeroUsize,
2727
path::{Path, PathBuf},
@@ -1735,6 +1735,31 @@ impl Editor {
17351735
.map(|_| ())
17361736
}
17371737

1738+
/// Insert the original [`lsp::Diagnostic`] for later use in the diagnostics picker.
1739+
pub fn add_diagnostics(
1740+
&mut self,
1741+
diagnostics: Vec<lsp::Diagnostic>,
1742+
path: lsp::Url,
1743+
server_id: usize,
1744+
) {
1745+
let mut diagnostics = diagnostics.into_iter().map(|d| (d, server_id)).collect();
1746+
match self.diagnostics.entry(path) {
1747+
Entry::Occupied(o) => {
1748+
let current_diagnostics = o.into_mut();
1749+
// there may entries of other language servers, which is why we can't overwrite the whole entry
1750+
current_diagnostics.retain(|(_, lsp_id)| *lsp_id != server_id);
1751+
current_diagnostics.append(&mut diagnostics);
1752+
// Sort diagnostics first by severity and then by line numbers.
1753+
// Note: The `lsp::DiagnosticSeverity` enum is already defined in decreasing order
1754+
current_diagnostics.sort_unstable_by_key(|(d, _)| (d.severity, d.range.start));
1755+
}
1756+
Entry::Vacant(v) => {
1757+
diagnostics.sort_unstable_by_key(|(d, _)| (d.severity, d.range.start));
1758+
v.insert(diagnostics);
1759+
}
1760+
};
1761+
}
1762+
17381763
pub async fn wait_event(&mut self) -> EditorEvent {
17391764
// the loop only runs once or twice and would be better implemented with a recursion + const generic
17401765
// however due to limitations with async functions that can not be implemented right now

0 commit comments

Comments
 (0)