aboutsummaryrefslogtreecommitdiff
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
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]>
-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
-rw-r--r--xtask/tests/tidy-tests/main.rs2
4 files changed, 97 insertions, 27 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 {
diff --git a/xtask/tests/tidy-tests/main.rs b/xtask/tests/tidy-tests/main.rs
index e5247854a..b3d6ddac9 100644
--- a/xtask/tests/tidy-tests/main.rs
+++ b/xtask/tests/tidy-tests/main.rs
@@ -34,7 +34,7 @@ fn check_todo(path: &Path, text: &str) {
34 } 34 }
35 if text.contains("TODO") || text.contains("TOOD") || text.contains("todo!") { 35 if text.contains("TODO") || text.contains("TOOD") || text.contains("todo!") {
36 panic!( 36 panic!(
37 "\nTODO markers should not be committed to the master branch,\n\ 37 "\nTODO markers or todo! macros should not be committed to the master branch,\n\
38 use FIXME instead\n\ 38 use FIXME instead\n\
39 {}\n", 39 {}\n",
40 path.display(), 40 path.display(),