aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2020-11-28 14:26:30 +0000
committerKirill Bulatov <[email protected]>2020-12-07 21:41:08 +0000
commit48acd7d455be43960d67632adc9eb176a10a8afe (patch)
tree033d93cf7311e1aafdf461a36ec085a431020850
parentdfd0626dbfea6816d38e6f72ce84f567877603e7 (diff)
Draft the new lsp handler
-rw-r--r--crates/completion/src/item.rs34
-rw-r--r--crates/rust-analyzer/src/caps.rs2
-rw-r--r--crates/rust-analyzer/src/handlers.rs10
-rw-r--r--crates/rust-analyzer/src/main_loop.rs1
-rw-r--r--crates/rust-analyzer/src/to_proto.rs29
5 files changed, 52 insertions, 24 deletions
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 @@
3use std::fmt; 3use std::fmt;
4 4
5use hir::{Documentation, ModPath, Mutability}; 5use hir::{Documentation, ModPath, Mutability};
6use ide_db::helpers::{ 6use ide_db::helpers::insert_use::{ImportScope, MergeBehaviour};
7 insert_use::{self, ImportScope, MergeBehaviour}, 7use syntax::TextRange;
8 mod_path_to_ast,
9};
10use syntax::{algo, TextRange};
11use text_edit::TextEdit; 8use text_edit::TextEdit;
12 9
13use crate::config::SnippetCap; 10use crate::config::SnippetCap;
@@ -65,6 +62,10 @@ pub struct CompletionItem {
65 /// Indicates that a reference or mutable reference to this variable is a 62 /// Indicates that a reference or mutable reference to this variable is a
66 /// possible match. 63 /// possible match.
67 ref_match: Option<(Mutability, CompletionScore)>, 64 ref_match: Option<(Mutability, CompletionScore)>,
65
66 /// The data later to be used in the `completionItem/resolve` response
67 /// to add the insert import edit.
68 import_to_add: Option<ImportToAdd>,
68} 69}
69 70
70// We use custom debug for CompletionItem to make snapshot tests more readable. 71// We use custom debug for CompletionItem to make snapshot tests more readable.
@@ -294,11 +295,9 @@ impl Builder {
294 let mut label = self.label; 295 let mut label = self.label;
295 let mut lookup = self.lookup; 296 let mut lookup = self.lookup;
296 let mut insert_text = self.insert_text; 297 let mut insert_text = self.insert_text;
297 let mut text_edits = TextEdit::builder();
298 298
299 if let Some(import_data) = self.import_to_add { 299 if let Some(import_to_add) = self.import_to_add.as_ref() {
300 let import = mod_path_to_ast(&import_data.import_path); 300 let mut import_path_without_last_segment = import_to_add.import_path.to_owned();
301 let mut import_path_without_last_segment = import_data.import_path;
302 let _ = import_path_without_last_segment.segments.pop(); 301 let _ = import_path_without_last_segment.segments.pop();
303 302
304 if !import_path_without_last_segment.segments.is_empty() { 303 if !import_path_without_last_segment.segments.is_empty() {
@@ -310,32 +309,20 @@ impl Builder {
310 } 309 }
311 label = format!("{}::{}", import_path_without_last_segment, label); 310 label = format!("{}::{}", import_path_without_last_segment, label);
312 } 311 }
313
314 let rewriter = insert_use::insert_use(
315 &import_data.import_scope,
316 import,
317 import_data.merge_behaviour,
318 );
319 if let Some(old_ast) = rewriter.rewrite_root() {
320 algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut text_edits);
321 }
322 } 312 }
323 313
324 let original_edit = match self.text_edit { 314 let text_edit = match self.text_edit {
325 Some(it) => it, 315 Some(it) => it,
326 None => { 316 None => {
327 TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone())) 317 TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone()))
328 } 318 }
329 }; 319 };
330 320
331 let mut resulting_edit = text_edits.finish();
332 resulting_edit.union(original_edit).expect("Failed to unite text edits");
333
334 CompletionItem { 321 CompletionItem {
335 source_range: self.source_range, 322 source_range: self.source_range,
336 label, 323 label,
337 insert_text_format: self.insert_text_format, 324 insert_text_format: self.insert_text_format,
338 text_edit: resulting_edit, 325 text_edit,
339 detail: self.detail, 326 detail: self.detail,
340 documentation: self.documentation, 327 documentation: self.documentation,
341 lookup, 328 lookup,
@@ -345,6 +332,7 @@ impl Builder {
345 trigger_call_info: self.trigger_call_info.unwrap_or(false), 332 trigger_call_info: self.trigger_call_info.unwrap_or(false),
346 score: self.score, 333 score: self.score,
347 ref_match: self.ref_match, 334 ref_match: self.ref_match,
335 import_to_add: self.import_to_add,
348 } 336 }
349 } 337 }
350 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder { 338 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> 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
30 })), 30 })),
31 hover_provider: Some(HoverProviderCapability::Simple(true)), 31 hover_provider: Some(HoverProviderCapability::Simple(true)),
32 completion_provider: Some(CompletionOptions { 32 completion_provider: Some(CompletionOptions {
33 resolve_provider: None, 33 resolve_provider: Some(true),
34 trigger_characters: Some(vec![":".to_string(), ".".to_string()]), 34 trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
35 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, 35 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
36 }), 36 }),
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(
577 Ok(Some(completion_list.into())) 577 Ok(Some(completion_list.into()))
578} 578}
579 579
580pub(crate) fn handle_resolve_completion(
581 snap: GlobalStateSnapshot,
582 original_completion: CompletionItem,
583) -> Result<CompletionItem> {
584 let _p = profile::span("handle_resolve_completion");
585 // TODO kb use the field to detect it's for autocompletion and do the insert logic
586 let _data = dbg!(original_completion).data;
587 Ok(original_completion)
588}
589
580pub(crate) fn handle_folding_range( 590pub(crate) fn handle_folding_range(
581 snap: GlobalStateSnapshot, 591 snap: GlobalStateSnapshot,
582 params: FoldingRangeParams, 592 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 {
454 .on::<lsp_types::request::GotoImplementation>(handlers::handle_goto_implementation) 454 .on::<lsp_types::request::GotoImplementation>(handlers::handle_goto_implementation)
455 .on::<lsp_types::request::GotoTypeDefinition>(handlers::handle_goto_type_definition) 455 .on::<lsp_types::request::GotoTypeDefinition>(handlers::handle_goto_type_definition)
456 .on::<lsp_types::request::Completion>(handlers::handle_completion) 456 .on::<lsp_types::request::Completion>(handlers::handle_completion)
457 .on::<lsp_types::request::ResolveCompletionItem>(handlers::handle_resolve_completion)
457 .on::<lsp_types::request::CodeLensRequest>(handlers::handle_code_lens) 458 .on::<lsp_types::request::CodeLensRequest>(handlers::handle_code_lens)
458 .on::<lsp_types::request::CodeLensResolve>(handlers::handle_code_lens_resolve) 459 .on::<lsp_types::request::CodeLensResolve>(handlers::handle_code_lens_resolve)
459 .on::<lsp_types::request::FoldingRangeRequest>(handlers::handle_folding_range) 460 .on::<lsp_types::request::FoldingRangeRequest>(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(
231 None => vec![res], 231 None => vec![res],
232 }; 232 };
233 233
234 // TODO kb need to get this logic away and store for the later resolve request
235 /*
236 let mut label = self.label;
237 let mut lookup = self.lookup;
238 let mut insert_text = self.insert_text;
239 let mut text_edits = TextEdit::builder();
240
241 if let Some((import_path, import_scope, merge_behaviour)) = completion_item.import_data.as_ref() {
242 let import = mod_path_to_ast(&import_path);
243 let mut import_path_without_last_segment = import_path;
244 let _ = import_path_without_last_segment.segments.pop();
245
246 if !import_path_without_last_segment.segments.is_empty() {
247 if lookup.is_none() {
248 lookup = Some(label.clone());
249 }
250 if insert_text.is_none() {
251 insert_text = Some(label.clone());
252 }
253 label = format!("{}::{}", import_path_without_last_segment, label);
254 }
255
256 let rewriter = insert_use(&import_scope, import, merge_behaviour);
257 if let Some(old_ast) = rewriter.rewrite_root() {
258 algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut text_edits);
259 }
260 }
261 */
262
234 for mut r in all_results.iter_mut() { 263 for mut r in all_results.iter_mut() {
235 r.insert_text_format = Some(insert_text_format(completion_item.insert_text_format())); 264 r.insert_text_format = Some(insert_text_format(completion_item.insert_text_format()));
236 } 265 }