From db2232ffa9ade4d1bbcc4958e9ecf32d37923f40 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Wed, 2 Mar 2022 23:08:15 +0530 Subject: [PATCH] Highlight current parameter in signature help --- helix-term/src/commands/lsp.rs | 33 ++++++++++++++++++++++++++------- helix-term/src/ui/lsp.rs | 10 ++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs index d700ae0017dd3..bf2dadb9b6f35 100644 --- a/helix-term/src/commands/lsp.rs +++ b/helix-term/src/commands/lsp.rs @@ -589,6 +589,7 @@ pub fn signature_help(cx: &mut Context) { .language() .and_then(|scope| scope.strip_prefix("source.")) .unwrap_or(""); + // If there are no signatures, response will be None, therefore // at least one signature exists. let signature = &response.signatures[response.active_signature.unwrap_or(0) as usize]; @@ -597,13 +598,31 @@ pub fn signature_help(cx: &mut Context) { language.to_string(), Arc::clone(&editor.syn_loader), ); - if let Some(ref signature_doc) = signature.documentation { - let doc_text = match signature_doc { - lsp::Documentation::String(s) => &s, - lsp::Documentation::MarkupContent(markup) => &markup.value, - }; - contents.set_signature_doc(doc_text.clone()); - } + + let signature_doc = signature.documentation.as_ref().map(|doc| match doc { + lsp::Documentation::String(s) => s.clone(), + lsp::Documentation::MarkupContent(markup) => markup.value.clone(), + }); + contents.set_signature_doc(signature_doc); + + let active_param_range = || -> Option<(usize, usize)> { + let param_idx = signature + .active_parameter + .or(response.active_parameter) + .unwrap_or(0) as usize; + let param = signature.parameters.as_ref()?.get(param_idx)?; + match ¶m.label { + lsp::ParameterLabel::Simple(string) => { + let start = signature.label.find(string.as_str())?; + Some((start, string.len())) + } + lsp::ParameterLabel::LabelOffsets([start, end]) => { + Some((*start as usize, *end as usize)) + } + } + }; + contents.set_active_param_range(active_param_range()); + let mut popup = Popup::new("signature-help", contents); let old_popup = compositor.find_id::>("signature-help"); popup.set_position(old_popup.and_then(|p| p.position().copied())); diff --git a/helix-term/src/ui/lsp.rs b/helix-term/src/ui/lsp.rs index 10c8a5b0e8cdd..9b248822d8941 100644 --- a/helix-term/src/ui/lsp.rs +++ b/helix-term/src/ui/lsp.rs @@ -46,12 +46,21 @@ impl Component for SignatureHelp { horizontal: 1, }; + let active_param_span = self.active_param_range.map(|(start, end)| { + vec![( + cx.editor.theme.find_scope_index("ui.selection").unwrap(), + start..end, + )] + }); + let sig_text = crate::ui::markdown::highlighted_code_block( self.signature.clone(), &self.language, Some(&cx.editor.theme), Arc::clone(&self.config_loader), + active_param_span, ); + let (_, sig_text_height) = crate::ui::text::required_size(&sig_text, area.width); let sig_text_area = area.clip_top(1).with_height(sig_text_height); let sig_text_para = Paragraph::new(sig_text).wrap(Wrap { trim: false }); @@ -95,6 +104,7 @@ impl Component for SignatureHelp { &self.language, None, Arc::clone(&self.config_loader), + None, ); let (sig_width, sig_height) = crate::ui::text::required_size(&signature_text, max_text_width);