on master help sign in
Send active diagnostics to LSP when requesting code actions. (#2005)
33b7483Robin Jadoul
helix-lsp/src/client.rs+2−1
@@ -842,11 +842,12 @@ impl Client {
842 &self,
842 &self,
843 text_document: lsp::TextDocumentIdentifier,
843 text_document: lsp::TextDocumentIdentifier,
844 range: lsp::Range,
844 range: lsp::Range,
845+ context: lsp::CodeActionContext,
845 ) -> impl Future<Output = Result<Value>> {
846 ) -> impl Future<Output = Result<Value>> {
846 let params = lsp::CodeActionParams {
847 let params = lsp::CodeActionParams {
847 text_document,
848 text_document,
848 range,
849 range,
849− context: lsp::CodeActionContext::default(),
850+ context,
850 work_done_progress_params: lsp::WorkDoneProgressParams::default(),
851 work_done_progress_params: lsp::WorkDoneProgressParams::default(),
851 partial_result_params: lsp::PartialResultParams::default(),
852 partial_result_params: lsp::PartialResultParams::default(),
852 };
853 };
helix-lsp/src/lib.rs+30
@@ -58,6 +58,36 @@ pub mod util {
58 use super::*;
58 use super::*;
59 use helix_core::{Range, Rope, Transaction};
59 use helix_core::{Range, Rope, Transaction};
60
60
61+ /// Converts a diagnostic in the document to [`lsp::Diagnostic`].
62+ ///
63+ /// Panics when [`pos_to_lsp_pos`] would for an invalid range on the diagnostic.
64+ pub fn diagnostic_to_lsp_diagnostic(
65+ doc: &Rope,
66+ diag: &helix_core::diagnostic::Diagnostic,
67+ offset_encoding: OffsetEncoding,
68+ ) -> lsp::Diagnostic {
69+ use helix_core::diagnostic::Severity::*;
70+
71+ let range = Range::new(diag.range.start, diag.range.end);
72+ let severity = diag.severity.map(|s| match s {
73+ Hint => lsp::DiagnosticSeverity::HINT,
74+ Info => lsp::DiagnosticSeverity::INFORMATION,
75+ Warning => lsp::DiagnosticSeverity::WARNING,
76+ Error => lsp::DiagnosticSeverity::ERROR,
77+ });
78+
79+ // TODO: add support for Diagnostic.data
80+ lsp::Diagnostic::new(
81+ range_to_lsp_range(doc, range, offset_encoding),
82+ severity,
83+ None,
84+ None,
85+ diag.message.to_owned(),
86+ None,
87+ None,
88+ )
89+ }
90+
61 /// Converts [`lsp::Position`] to a position in the document.
91 /// Converts [`lsp::Position`] to a position in the document.
62 ///
92 ///
63 /// Returns `None` if position exceeds document length or an operation overflows.
93 /// Returns `None` if position exceeds document length or an operation overflows.
helix-term/src/commands/lsp.rs+22−8
@@ -1,6 +1,6 @@
1use helix_lsp::{
1use helix_lsp::{
2 block_on, lsp,
2 block_on, lsp,
3− util::{lsp_pos_to_pos, lsp_range_to_range, range_to_lsp_range},
3+ util::{diagnostic_to_lsp_diagnostic, lsp_pos_to_pos, lsp_range_to_range, range_to_lsp_range},
4 OffsetEncoding,
4 OffsetEncoding,
5};
5};
6
6
@@ -192,15 +192,29 @@ pub fn code_action(cx: &mut Context) {
192
192
193 let language_server = language_server!(cx.editor, doc);
193 let language_server = language_server!(cx.editor, doc);
194
194
195− let range = range_to_lsp_range(
196− doc.text(),
197− doc.selection(view.id).primary(),
195+ let selection_range = doc.selection(view.id).primary();
198− language_server.offset_encoding(),
199− );
200−
201− let future = language_server.code_actions(doc.identifier(), range);
202 let offset_encoding = language_server.offset_encoding();
196 let offset_encoding = language_server.offset_encoding();
203
197
198+ let range = range_to_lsp_range(doc.text(), selection_range, offset_encoding);
199+
200+ let future = language_server.code_actions(
201+ doc.identifier(),
202+ range,
203+ // Filter and convert overlapping diagnostics
204+ lsp::CodeActionContext {
205+ diagnostics: doc
206+ .diagnostics()
207+ .iter()
208+ .filter(|&diag| {
209+ selection_range
210+ .overlaps(&helix_core::Range::new(diag.range.start, diag.range.end))
211+ })
212+ .map(|diag| diagnostic_to_lsp_diagnostic(doc.text(), diag, offset_encoding))
213+ .collect(),
214+ only: None,
215+ },
216+ );
217+
204 cx.callback(
218 cx.callback(
205 future,
219 future,
206 move |editor, compositor, response: Option<lsp::CodeActionResponse>| {
220 move |editor, compositor, response: Option<lsp::CodeActionResponse>| {