From e1e79cf0648624e7a3787d0013c0c7e86210772f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 16 Jul 2020 18:41:16 +0200 Subject: Take label offets client capability into account --- crates/rust-analyzer/src/config.rs | 10 ++++++ crates/rust-analyzer/src/handlers.rs | 6 +++- crates/rust-analyzer/src/to_proto.rs | 60 ++++++++++++++++++++++++++++++------ 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index ed5e52871..68b2a2abd 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -127,6 +127,7 @@ pub struct ClientCapsConfig { pub resolve_code_action: bool, pub hover_actions: bool, pub status_notification: bool, + pub signature_help_label_offsets: bool, } impl Config { @@ -302,6 +303,15 @@ impl Config { { self.client_caps.code_action_literals = value; } + if let Some(value) = doc_caps + .signature_help + .as_ref() + .and_then(|it| it.signature_information.as_ref()) + .and_then(|it| it.parameter_information.as_ref()) + .and_then(|it| it.label_offset_support) + { + self.client_caps.signature_help_label_offsets = value; + } self.completion.allow_snippets(false); if let Some(completion) = &doc_caps.completion { diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 447d73fd4..18d660f42 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -557,7 +557,11 @@ pub(crate) fn handle_signature_help( None => return Ok(None), }; let concise = !snap.config.call_info_full; - let res = to_proto::signature_help(call_info, concise); + let res = to_proto::signature_help( + call_info, + concise, + snap.config.client_caps.signature_help_label_offsets, + ); Ok(Some(res)) } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 43fc52848..7fcb43a4f 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -219,16 +219,58 @@ pub(crate) fn completion_item( res } -pub(crate) fn signature_help(call_info: CallInfo, concise: bool) -> lsp_types::SignatureHelp { - let parameters = call_info - .parameter_labels() - .map(|label| lsp_types::ParameterInformation { - label: lsp_types::ParameterLabel::Simple(label.to_string()), - documentation: None, - }) - .collect(); +pub(crate) fn signature_help( + call_info: CallInfo, + concise: bool, + label_offsets: bool, +) -> lsp_types::SignatureHelp { + let (label, parameters) = match (concise, label_offsets) { + (_, false) => { + let params = call_info + .parameter_labels() + .map(|label| lsp_types::ParameterInformation { + label: lsp_types::ParameterLabel::Simple(label.to_string()), + documentation: None, + }) + .collect::>(); + let label = + if concise { call_info.parameter_labels().join(", ") } else { call_info.signature }; + (label, params) + } + (false, true) => { + let params = call_info + .parameter_ranges() + .iter() + .map(|it| [u32::from(it.start()).into(), u32::from(it.end()).into()]) + .map(|label_offsets| lsp_types::ParameterInformation { + label: lsp_types::ParameterLabel::LabelOffsets(label_offsets), + documentation: None, + }) + .collect::>(); + (call_info.signature, params) + } + (true, true) => { + let mut params = Vec::new(); + let mut label = String::new(); + let mut first = true; + for param in call_info.parameter_labels() { + if !first { + label.push_str(", "); + } + first = false; + let start = label.len() as u64; + label.push_str(param); + let end = label.len() as u64; + params.push(lsp_types::ParameterInformation { + label: lsp_types::ParameterLabel::LabelOffsets([start, end]), + documentation: None, + }); + } + + (label, params) + } + }; - let label = if concise { call_info.parameter_labels().join(", ") } else { call_info.signature }; let documentation = call_info.doc.map(|doc| { lsp_types::Documentation::MarkupContent(lsp_types::MarkupContent { kind: lsp_types::MarkupKind::Markdown, -- cgit v1.2.3