aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion/completion_item.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion/completion_item.rs')
-rw-r--r--crates/ra_ide/src/completion/completion_item.rs72
1 files changed, 71 insertions, 1 deletions
diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs
index bc0f1aff5..a3ae9c86b 100644
--- a/crates/ra_ide/src/completion/completion_item.rs
+++ b/crates/ra_ide/src/completion/completion_item.rs
@@ -2,7 +2,9 @@
2 2
3use std::fmt; 3use std::fmt;
4 4
5use hir::Documentation; 5use super::completion_context::CompletionContext;
6use crate::call_info::call_info;
7use hir::{Documentation, HirDisplay};
6use ra_syntax::TextRange; 8use ra_syntax::TextRange;
7use ra_text_edit::TextEdit; 9use ra_text_edit::TextEdit;
8 10
@@ -51,6 +53,9 @@ pub struct CompletionItem {
51 /// If completing a function call, ask the editor to show parameter popup 53 /// If completing a function call, ask the editor to show parameter popup
52 /// after completion. 54 /// after completion.
53 trigger_call_info: bool, 55 trigger_call_info: bool,
56
57 /// Score is usefull to pre select or display in better order completion items
58 score: Option<CompletionScore>,
54} 59}
55 60
56// We use custom debug for CompletionItem to make `insta`'s diffs more readable. 61// We use custom debug for CompletionItem to make `insta`'s diffs more readable.
@@ -80,6 +85,9 @@ impl fmt::Debug for CompletionItem {
80 if self.deprecated { 85 if self.deprecated {
81 s.field("deprecated", &true); 86 s.field("deprecated", &true);
82 } 87 }
88 if let Some(score) = &self.score {
89 s.field("score", score);
90 }
83 if self.trigger_call_info { 91 if self.trigger_call_info {
84 s.field("trigger_call_info", &true); 92 s.field("trigger_call_info", &true);
85 } 93 }
@@ -147,6 +155,7 @@ impl CompletionItem {
147 text_edit: None, 155 text_edit: None,
148 deprecated: None, 156 deprecated: None,
149 trigger_call_info: None, 157 trigger_call_info: None,
158 score: None,
150 } 159 }
151 } 160 }
152 /// What user sees in pop-up in the UI. 161 /// What user sees in pop-up in the UI.
@@ -186,6 +195,14 @@ impl CompletionItem {
186 self.deprecated 195 self.deprecated
187 } 196 }
188 197
198 pub fn score(&self) -> Option<CompletionScore> {
199 self.score.clone()
200 }
201
202 pub fn set_score(&mut self, score: CompletionScore) {
203 self.score = Some(score);
204 }
205
189 pub fn trigger_call_info(&self) -> bool { 206 pub fn trigger_call_info(&self) -> bool {
190 self.trigger_call_info 207 self.trigger_call_info
191 } 208 }
@@ -206,6 +223,7 @@ pub(crate) struct Builder {
206 text_edit: Option<TextEdit>, 223 text_edit: Option<TextEdit>,
207 deprecated: Option<bool>, 224 deprecated: Option<bool>,
208 trigger_call_info: Option<bool>, 225 trigger_call_info: Option<bool>,
226 score: Option<CompletionScore>,
209} 227}
210 228
211impl Builder { 229impl Builder {
@@ -235,6 +253,7 @@ impl Builder {
235 completion_kind: self.completion_kind, 253 completion_kind: self.completion_kind,
236 deprecated: self.deprecated.unwrap_or(false), 254 deprecated: self.deprecated.unwrap_or(false),
237 trigger_call_info: self.trigger_call_info.unwrap_or(false), 255 trigger_call_info: self.trigger_call_info.unwrap_or(false),
256 score: self.score,
238 } 257 }
239 } 258 }
240 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder { 259 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder {
@@ -285,6 +304,51 @@ impl Builder {
285 self.deprecated = Some(deprecated); 304 self.deprecated = Some(deprecated);
286 self 305 self
287 } 306 }
307 #[allow(unused)]
308 pub(crate) fn compute_score(mut self, ctx: &CompletionContext) -> Builder {
309 let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax {
310 if let Some((struct_field, _)) = ctx.sema.resolve_record_field(record_field) {
311 (
312 struct_field.name(ctx.db).to_string(),
313 struct_field.signature_ty(ctx.db).display(ctx.db).to_string(),
314 )
315 } else {
316 return self;
317 }
318 } else if let Some(call_info) = call_info(ctx.db, ctx.file_position) {
319 if call_info.active_parameter_type().is_some()
320 && call_info.active_parameter_name().is_some()
321 {
322 (
323 call_info.active_parameter_name().unwrap(),
324 call_info.active_parameter_type().unwrap(),
325 )
326 } else {
327 return self;
328 }
329 } else {
330 return self;
331 };
332
333 // Compute score
334 // For the same type
335 if let Some(a_parameter_type) = &self.detail {
336 if &active_type == a_parameter_type {
337 // If same type + same name then go top position
338 if active_name == self.label {
339 return self.set_score(CompletionScore::TypeAndNameMatch);
340 } else {
341 return self.set_score(CompletionScore::TypeMatch);
342 }
343 }
344 }
345
346 self
347 }
348 pub(crate) fn set_score(mut self, score: CompletionScore) -> Builder {
349 self.score = Some(score);
350 self
351 }
288 pub(crate) fn trigger_call_info(mut self) -> Builder { 352 pub(crate) fn trigger_call_info(mut self) -> Builder {
289 self.trigger_call_info = Some(true); 353 self.trigger_call_info = Some(true);
290 self 354 self
@@ -297,6 +361,12 @@ impl<'a> Into<CompletionItem> for Builder {
297 } 361 }
298} 362}
299 363
364#[derive(Debug, Clone)]
365pub enum CompletionScore {
366 TypeMatch,
367 TypeAndNameMatch,
368}
369
300/// Represents an in-progress set of completions being built. 370/// Represents an in-progress set of completions being built.
301#[derive(Debug, Default)] 371#[derive(Debug, Default)]
302pub(crate) struct Completions { 372pub(crate) struct Completions {