From 48acd7d455be43960d67632adc9eb176a10a8afe Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 28 Nov 2020 16:26:30 +0200 Subject: Draft the new lsp handler --- crates/completion/src/item.rs | 34 +++++++++++----------------------- crates/rust-analyzer/src/caps.rs | 2 +- crates/rust-analyzer/src/handlers.rs | 10 ++++++++++ crates/rust-analyzer/src/main_loop.rs | 1 + crates/rust-analyzer/src/to_proto.rs | 29 +++++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 24 deletions(-) (limited to 'crates') diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs index e85549fef..ce6a44e57 100644 --- a/crates/completion/src/item.rs +++ b/crates/completion/src/item.rs @@ -3,11 +3,8 @@ use std::fmt; use hir::{Documentation, ModPath, Mutability}; -use ide_db::helpers::{ - insert_use::{self, ImportScope, MergeBehaviour}, - mod_path_to_ast, -}; -use syntax::{algo, TextRange}; +use ide_db::helpers::insert_use::{ImportScope, MergeBehaviour}; +use syntax::TextRange; use text_edit::TextEdit; use crate::config::SnippetCap; @@ -65,6 +62,10 @@ pub struct CompletionItem { /// Indicates that a reference or mutable reference to this variable is a /// possible match. ref_match: Option<(Mutability, CompletionScore)>, + + /// The data later to be used in the `completionItem/resolve` response + /// to add the insert import edit. + import_to_add: Option, } // We use custom debug for CompletionItem to make snapshot tests more readable. @@ -294,11 +295,9 @@ impl Builder { let mut label = self.label; let mut lookup = self.lookup; let mut insert_text = self.insert_text; - let mut text_edits = TextEdit::builder(); - if let Some(import_data) = self.import_to_add { - let import = mod_path_to_ast(&import_data.import_path); - let mut import_path_without_last_segment = import_data.import_path; + if let Some(import_to_add) = self.import_to_add.as_ref() { + let mut import_path_without_last_segment = import_to_add.import_path.to_owned(); let _ = import_path_without_last_segment.segments.pop(); if !import_path_without_last_segment.segments.is_empty() { @@ -310,32 +309,20 @@ impl Builder { } label = format!("{}::{}", import_path_without_last_segment, label); } - - let rewriter = insert_use::insert_use( - &import_data.import_scope, - import, - import_data.merge_behaviour, - ); - if let Some(old_ast) = rewriter.rewrite_root() { - algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut text_edits); - } } - let original_edit = match self.text_edit { + let text_edit = match self.text_edit { Some(it) => it, None => { TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone())) } }; - let mut resulting_edit = text_edits.finish(); - resulting_edit.union(original_edit).expect("Failed to unite text edits"); - CompletionItem { source_range: self.source_range, label, insert_text_format: self.insert_text_format, - text_edit: resulting_edit, + text_edit, detail: self.detail, documentation: self.documentation, lookup, @@ -345,6 +332,7 @@ impl Builder { trigger_call_info: self.trigger_call_info.unwrap_or(false), score: self.score, ref_match: self.ref_match, + import_to_add: self.import_to_add, } } pub(crate) fn lookup_by(mut self, lookup: impl Into) -> Builder { diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index c7203451c..c559e1a3d 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs @@ -30,7 +30,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti })), hover_provider: Some(HoverProviderCapability::Simple(true)), completion_provider: Some(CompletionOptions { - resolve_provider: None, + resolve_provider: Some(true), trigger_characters: Some(vec![":".to_string(), ".".to_string()]), work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, }), diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 1cf4139d2..255a6e489 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -577,6 +577,16 @@ pub(crate) fn handle_completion( Ok(Some(completion_list.into())) } +pub(crate) fn handle_resolve_completion( + snap: GlobalStateSnapshot, + original_completion: CompletionItem, +) -> Result { + let _p = profile::span("handle_resolve_completion"); + // TODO kb use the field to detect it's for autocompletion and do the insert logic + let _data = dbg!(original_completion).data; + Ok(original_completion) +} + pub(crate) fn handle_folding_range( snap: GlobalStateSnapshot, params: FoldingRangeParams, diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 55d46b09e..12b0946ac 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -454,6 +454,7 @@ impl GlobalState { .on::(handlers::handle_goto_implementation) .on::(handlers::handle_goto_type_definition) .on::(handlers::handle_completion) + .on::(handlers::handle_resolve_completion) .on::(handlers::handle_code_lens) .on::(handlers::handle_code_lens_resolve) .on::(handlers::handle_folding_range) diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 01eabe852..db9ed08f6 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -231,6 +231,35 @@ pub(crate) fn completion_item( None => vec![res], }; + // TODO kb need to get this logic away and store for the later resolve request + /* + let mut label = self.label; + let mut lookup = self.lookup; + let mut insert_text = self.insert_text; + let mut text_edits = TextEdit::builder(); + + if let Some((import_path, import_scope, merge_behaviour)) = completion_item.import_data.as_ref() { + let import = mod_path_to_ast(&import_path); + let mut import_path_without_last_segment = import_path; + let _ = import_path_without_last_segment.segments.pop(); + + if !import_path_without_last_segment.segments.is_empty() { + if lookup.is_none() { + lookup = Some(label.clone()); + } + if insert_text.is_none() { + insert_text = Some(label.clone()); + } + label = format!("{}::{}", import_path_without_last_segment, label); + } + + let rewriter = insert_use(&import_scope, import, merge_behaviour); + if let Some(old_ast) = rewriter.rewrite_root() { + algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut text_edits); + } + } + */ + for mut r in all_results.iter_mut() { r.insert_text_format = Some(insert_text_format(completion_item.insert_text_format())); } -- cgit v1.2.3