From 5d7b5db8ab284e0c2a41e6fbda08857f87406780 Mon Sep 17 00:00:00 2001 From: Gabriel Berto Date: Sat, 25 Dec 2021 07:00:57 -0300 Subject: [PATCH] Resolve completion item (#1315) Co-authored-by: Gabriel Berto --- helix-lsp/src/client.rs | 8 +++++++ helix-term/src/ui/completion.rs | 40 +++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index f1de87524..43804daa9 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -556,6 +556,14 @@ impl Client { self.call::(params) } + pub async fn resolve_completion_item( + &self, + completion_item: lsp::CompletionItem, + ) -> Result { + self.request::(completion_item) + .await + } + pub fn text_document_signature_help( &self, text_document: lsp::TextDocumentIdentifier, diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index a55201ff2..274330c0e 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -154,8 +154,19 @@ impl Completion { ); doc.apply(&transaction, view.id); - if let Some(additional_edits) = &item.additional_text_edits { - // gopls uses this to add extra imports + // apply additional edits, mostly used to auto import unqualified types + let resolved_additional_text_edits = if item.additional_text_edits.is_some() { + None + } else { + Completion::resolve_completion_item(doc, item.clone()) + .and_then(|item| item.additional_text_edits) + }; + + if let Some(additional_edits) = item + .additional_text_edits + .as_ref() + .or_else(|| resolved_additional_text_edits.as_ref()) + { if !additional_edits.is_empty() { let transaction = util::generate_transaction_from_edits( doc.text(), @@ -181,6 +192,31 @@ impl Completion { completion } + fn resolve_completion_item( + doc: &Document, + completion_item: lsp::CompletionItem, + ) -> Option { + let language_server = doc.language_server()?; + let completion_resolve_provider = language_server + .capabilities() + .completion_provider + .as_ref()? + .resolve_provider; + if completion_resolve_provider != Some(true) { + return None; + } + + let future = language_server.resolve_completion_item(completion_item); + let response = helix_lsp::block_on(future); + match response { + Ok(completion_item) => Some(completion_item), + Err(err) => { + log::error!("execute LSP command: {}", err); + None + } + } + } + pub fn recompute_filter(&mut self, editor: &Editor) { // recompute menu based on matches let menu = self.popup.contents_mut();