diff options
author | Benjamin Coenen <[email protected]> | 2020-04-12 16:45:07 +0100 |
---|---|---|
committer | Benjamin Coenen <[email protected]> | 2020-04-12 16:58:06 +0100 |
commit | 064095742980d4c825391f643e437520599f51d8 (patch) | |
tree | 339ac072c6d7c76451804db1f85bc673b9798137 /crates/ra_ide | |
parent | 93bfc2d05d36a47dc05a1799210327473d702dbc (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')
-rw-r--r-- | crates/ra_ide/src/completion.rs | 3 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_dot.rs | 69 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/completion_item.rs | 50 |
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 | ||
3 | use hir::{HasVisibility, HirDisplay, Type}; | 3 | use hir::{ |
4 | HasVisibility, | ||
5 | // HirDisplay, | ||
6 | Type, | ||
7 | }; | ||
4 | 8 | ||
5 | use crate::completion::completion_item::CompletionKind; | 9 | use crate::completion::completion_item::CompletionKind; |
6 | use crate::{ | 10 | use 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 | }; |
10 | use rustc_hash::FxHashSet; | 19 | use rustc_hash::FxHashSet; |
11 | use 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). |
14 | pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { | 23 | pub(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 | ||
39 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { | 48 | fn 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 | ||
3 | use std::fmt; | 3 | use std::{cmp::Ordering, fmt}; |
4 | 4 | ||
5 | use crate::CallInfo; | ||
5 | use hir::Documentation; | 6 | use hir::Documentation; |
6 | use ra_syntax::TextRange; | 7 | use ra_syntax::TextRange; |
7 | use ra_text_edit::TextEdit; | 8 | use ra_text_edit::TextEdit; |
@@ -297,10 +298,17 @@ impl<'a> Into<CompletionItem> for Builder { | |||
297 | } | 298 | } |
298 | } | 299 | } |
299 | 300 | ||
301 | #[derive(Debug)] | ||
302 | pub(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)] |
302 | pub(crate) struct Completions { | 309 | pub(crate) struct Completions { |
303 | buf: Vec<CompletionItem>, | 310 | buf: Vec<CompletionItem>, |
311 | sort_option: Option<SortOption>, | ||
304 | } | 312 | } |
305 | 313 | ||
306 | impl Completions { | 314 | impl 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 | ||
319 | impl Into<Vec<CompletionItem>> for Completions { | 367 | impl Into<Vec<CompletionItem>> for Completions { |