From 1c3a1385a587f0713908c0ae888ffad31f13de11 Mon Sep 17 00:00:00 2001 From: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> Date: Tue, 21 Apr 2020 14:31:57 +0200 Subject: Improve autocompletion by looking on the type and name Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> --- crates/ra_ide/src/completion/complete_dot.rs | 2 -- crates/ra_ide/src/completion/completion_item.rs | 42 ++-------------------- crates/ra_ide/src/completion/presentation.rs | 48 ++++++++++++++++++++++--- crates/ra_ide/src/display/function_signature.rs | 3 +- 4 files changed, 47 insertions(+), 48 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs index c16357a7e..44288f92e 100644 --- a/crates/ra_ide/src/completion/complete_dot.rs +++ b/crates/ra_ide/src/completion/complete_dot.rs @@ -7,11 +7,9 @@ use crate::{ completion_context::CompletionContext, completion_item::{CompletionKind, Completions}, }, - // CallInfo, CompletionItem, }; use rustc_hash::FxHashSet; -// use std::cmp::Ordering; /// Complete dot accesses, i.e. fields or methods (and .await syntax). pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs index a3ae9c86b..8b96b81db 100644 --- a/crates/ra_ide/src/completion/completion_item.rs +++ b/crates/ra_ide/src/completion/completion_item.rs @@ -305,46 +305,6 @@ impl Builder { self } #[allow(unused)] - pub(crate) fn compute_score(mut self, ctx: &CompletionContext) -> Builder { - let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { - if let Some((struct_field, _)) = ctx.sema.resolve_record_field(record_field) { - ( - struct_field.name(ctx.db).to_string(), - struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), - ) - } else { - return self; - } - } else if let Some(call_info) = call_info(ctx.db, ctx.file_position) { - if call_info.active_parameter_type().is_some() - && call_info.active_parameter_name().is_some() - { - ( - call_info.active_parameter_name().unwrap(), - call_info.active_parameter_type().unwrap(), - ) - } else { - return self; - } - } else { - return self; - }; - - // Compute score - // For the same type - if let Some(a_parameter_type) = &self.detail { - if &active_type == a_parameter_type { - // If same type + same name then go top position - if active_name == self.label { - return self.set_score(CompletionScore::TypeAndNameMatch); - } else { - return self.set_score(CompletionScore::TypeMatch); - } - } - } - - self - } pub(crate) fn set_score(mut self, score: CompletionScore) -> Builder { self.score = Some(score); self @@ -363,7 +323,9 @@ impl<'a> Into for Builder { #[derive(Debug, Clone)] pub enum CompletionScore { + /// If only type match TypeMatch, + /// If type and name match TypeAndNameMatch, } diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 5c3360ce4..bb12a1bdc 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -6,12 +6,13 @@ use stdx::SepBy; use test_utils::tested_by; use crate::{ + call_info::call_info, completion::{ completion_item::Builder, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, }, display::{const_label, macro_label, type_label, FunctionSignature}, - RootDatabase, + CompletionScore, RootDatabase, }; impl Completions { @@ -22,7 +23,7 @@ impl Completions { ty: &Type, ) { let is_deprecated = is_deprecated(field, ctx.db); - CompletionItem::new( + let mut completion_item = CompletionItem::new( CompletionKind::Reference, ctx.source_range(), field.name(ctx.db).to_string(), @@ -31,8 +32,11 @@ impl Completions { .detail(ty.display(ctx.db).to_string()) .set_documentation(field.docs(ctx.db)) .set_deprecated(is_deprecated) - .compute_score(ctx) - .add_to(self); + .build(); + + compute_score(&mut completion_item, ctx); + + self.add(completion_item); } pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &Type) { @@ -295,6 +299,42 @@ impl Completions { } } +pub(crate) fn compute_score(completion_item: &mut CompletionItem, ctx: &CompletionContext) { + let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { + if let Some((struct_field, _)) = ctx.sema.resolve_record_field(record_field) { + ( + struct_field.name(ctx.db).to_string(), + struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), + ) + } else { + return; + } + } else if let Some(call_info) = call_info(ctx.db, ctx.file_position) { + if call_info.active_parameter_type().is_some() + && call_info.active_parameter_name().is_some() + { + (call_info.active_parameter_name().unwrap(), call_info.active_parameter_type().unwrap()) + } else { + return; + } + } else { + return; + }; + + // Compute score + // For the same type + if let Some(a_parameter_type) = completion_item.detail() { + if &active_type == a_parameter_type { + // If same type + same name then go top position + if active_name == completion_item.label() { + completion_item.set_score(CompletionScore::TypeAndNameMatch); + } else { + completion_item.set_score(CompletionScore::TypeMatch); + } + } + } +} + enum Params { Named(Vec), Anonymous(usize), diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs index 2d175882b..b5e2785fe 100644 --- a/crates/ra_ide/src/display/function_signature.rs +++ b/crates/ra_ide/src/display/function_signature.rs @@ -73,7 +73,7 @@ impl FunctionSignature { if let Some(param_type) = raw_param.split(':').nth(1) { parameter_types.push(param_type[1..].to_string()); } else { - // The unwrap_or_else is useful when you have tuple struct + // useful when you have tuple struct parameter_types.push(raw_param.clone()); } params.push(raw_param); @@ -177,7 +177,6 @@ impl From<&'_ ast::FnDef> for FunctionSignature { has_self_param = true; let raw_param = self_param.syntax().text().to_string(); - // FIXME: better solution ? res_types.push( raw_param.split(':').nth(1).unwrap_or_else(|| " Self")[1..].to_string(), ); -- cgit v1.2.3