aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src
diff options
context:
space:
mode:
authorBenjamin Coenen <[email protected]>2020-04-12 16:45:07 +0100
committerBenjamin Coenen <[email protected]>2020-04-12 16:58:06 +0100
commit064095742980d4c825391f643e437520599f51d8 (patch)
tree339ac072c6d7c76451804db1f85bc673b9798137 /crates/ra_ide/src
parent93bfc2d05d36a47dc05a1799210327473d702dbc (diff)
Improve autocompletion by looking on the type and name, change implementation, include sort in Completions struct
Signed-off-by: Benjamin Coenen <[email protected]>
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r--crates/ra_ide/src/completion.rs3
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs69
-rw-r--r--crates/ra_ide/src/completion/completion_item.rs50
3 files changed, 96 insertions, 26 deletions
diff --git a/crates/ra_ide/src/completion.rs b/crates/ra_ide/src/completion.rs
index 4a1a2a04a..3be8b1903 100644
--- a/crates/ra_ide/src/completion.rs
+++ b/crates/ra_ide/src/completion.rs
@@ -94,5 +94,8 @@ pub(crate) fn completions(
94 complete_macro_in_item_position::complete_macro_in_item_position(&mut acc, &ctx); 94 complete_macro_in_item_position::complete_macro_in_item_position(&mut acc, &ctx);
95 complete_trait_impl::complete_trait_impl(&mut acc, &ctx); 95 complete_trait_impl::complete_trait_impl(&mut acc, &ctx);
96 96
97 // Reorder completion items if there is a sort_option
98 acc.sort();
99
97 Some(acc) 100 Some(acc)
98} 101}
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index b5448af5c..cb899d8ff 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -1,14 +1,23 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{HasVisibility, HirDisplay, Type}; 3use hir::{
4 HasVisibility,
5 // HirDisplay,
6 Type,
7};
4 8
5use crate::completion::completion_item::CompletionKind; 9use crate::completion::completion_item::CompletionKind;
6use crate::{ 10use crate::{
7 completion::{completion_context::CompletionContext, completion_item::Completions}, 11 call_info::call_info,
12 completion::{
13 completion_context::CompletionContext,
14 completion_item::{Completions, SortOption},
15 },
16 // CallInfo,
8 CompletionItem, 17 CompletionItem,
9}; 18};
10use rustc_hash::FxHashSet; 19use rustc_hash::FxHashSet;
11use std::cmp::Ordering; 20// use std::cmp::Ordering;
12 21
13/// Complete dot accesses, i.e. fields or methods (and .await syntax). 22/// Complete dot accesses, i.e. fields or methods (and .await syntax).
14pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { 23pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
@@ -38,30 +47,40 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
38 47
39fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { 48fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) {
40 for receiver in receiver.autoderef(ctx.db) { 49 for receiver in receiver.autoderef(ctx.db) {
41 let mut fields = receiver.fields(ctx.db); 50 let fields = receiver.fields(ctx.db);
42 if let Some(call_info) = &ctx.call_info { 51
43 if let Some(active_parameter_type) = call_info.active_parameter_type() { 52 // If we use this implementation we can delete call_info in the CompletionContext
44 let active_parameter_name = call_info.active_parameter_name().unwrap(); 53 if let Some(call_info) = call_info(ctx.db, ctx.file_position) {
45 fields.sort_by(|a, b| { 54 acc.with_sort_option(SortOption::CallFn(call_info));
46 // For the same type
47 if active_parameter_type == a.1.display(ctx.db).to_string() {
48 // If same type + same name then go top position
49 if active_parameter_name == a.0.name(ctx.db).to_string() {
50 Ordering::Less
51 } else {
52 if active_parameter_type == b.1.display(ctx.db).to_string() {
53 Ordering::Equal
54 } else {
55 Ordering::Less
56 }
57 }
58 } else {
59 Ordering::Greater
60 }
61 });
62 }
63 } 55 }
64 56
57 // // For Call Fn
58 // if let Some(call_info) = &ctx.call_info {
59 // if let Some(active_parameter_type) = call_info.active_parameter_type() {
60 // let active_parameter_name = call_info.active_parameter_name().unwrap();
61 // fields.sort_by(|a, b| {
62 // // For the same type
63 // if active_parameter_type == a.1.display(ctx.db).to_string() {
64 // // If same type + same name then go top position
65 // if active_parameter_name == a.0.name(ctx.db).to_string() {
66 // Ordering::Less
67 // } else {
68 // if active_parameter_type == b.1.display(ctx.db).to_string() {
69 // Ordering::Equal
70 // } else {
71 // Ordering::Less
72 // }
73 // }
74 // } else {
75 // Ordering::Greater
76 // }
77 // });
78 // }
79 // }
80
81 // For Lit struct fields
82 // ---
83
65 for (field, ty) in fields { 84 for (field, ty) in fields {
66 if ctx.scope().module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) { 85 if ctx.scope().module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) {
67 // Skip private field. FIXME: If the definition location of the 86 // Skip private field. FIXME: If the definition location of the
diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs
index bc0f1aff5..f8e6e53f1 100644
--- a/crates/ra_ide/src/completion/completion_item.rs
+++ b/crates/ra_ide/src/completion/completion_item.rs
@@ -1,7 +1,8 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::fmt; 3use std::{cmp::Ordering, fmt};
4 4
5use crate::CallInfo;
5use hir::Documentation; 6use hir::Documentation;
6use ra_syntax::TextRange; 7use ra_syntax::TextRange;
7use ra_text_edit::TextEdit; 8use ra_text_edit::TextEdit;
@@ -297,10 +298,17 @@ impl<'a> Into<CompletionItem> for Builder {
297 } 298 }
298} 299}
299 300
301#[derive(Debug)]
302pub(crate) enum SortOption {
303 CallFn(CallInfo),
304 // LitStruct,
305}
306
300/// Represents an in-progress set of completions being built. 307/// Represents an in-progress set of completions being built.
301#[derive(Debug, Default)] 308#[derive(Debug, Default)]
302pub(crate) struct Completions { 309pub(crate) struct Completions {
303 buf: Vec<CompletionItem>, 310 buf: Vec<CompletionItem>,
311 sort_option: Option<SortOption>,
304} 312}
305 313
306impl Completions { 314impl Completions {
@@ -314,6 +322,46 @@ impl Completions {
314 { 322 {
315 items.into_iter().for_each(|item| self.add(item.into())) 323 items.into_iter().for_each(|item| self.add(item.into()))
316 } 324 }
325
326 pub(crate) fn with_sort_option(&mut self, sort_option: SortOption) {
327 self.sort_option = Some(sort_option);
328 }
329
330 pub(crate) fn sort(&mut self) {
331 if self.sort_option.is_none() {
332 return;
333 }
334 let sort_option = self.sort_option.as_ref().unwrap();
335
336 match sort_option {
337 SortOption::CallFn(call_info) => {
338 if let Some(active_parameter_type) = call_info.active_parameter_type() {
339 let active_parameter_name = call_info.active_parameter_name().unwrap();
340
341 self.buf.sort_by(|a, b| {
342 // For the same type
343 if let Some(a_parameter_type) = &a.detail {
344 if &active_parameter_type == a_parameter_type {
345 // If same type + same name then go top position
346 if active_parameter_name != a.label {
347 if let Some(b_parameter_type) = &b.detail {
348 if &active_parameter_type == b_parameter_type {
349 return Ordering::Equal;
350 }
351 }
352 }
353 Ordering::Less
354 } else {
355 Ordering::Greater
356 }
357 } else {
358 Ordering::Greater
359 }
360 });
361 }
362 } // _ => unimplemented!("sort options not already implemented"),
363 }
364 }
317} 365}
318 366
319impl Into<Vec<CompletionItem>> for Completions { 367impl Into<Vec<CompletionItem>> for Completions {