diff options
-rw-r--r-- | crates/ra_analysis/src/completion.rs | 19 | ||||
-rw-r--r-- | crates/ra_analysis/src/completion/completion_item.rs | 13 | ||||
-rw-r--r-- | crates/ra_analysis/src/completion/reference_completion.rs | 32 |
3 files changed, 38 insertions, 26 deletions
diff --git a/crates/ra_analysis/src/completion.rs b/crates/ra_analysis/src/completion.rs index 222b6854c..074033ad8 100644 --- a/crates/ra_analysis/src/completion.rs +++ b/crates/ra_analysis/src/completion.rs | |||
@@ -15,7 +15,8 @@ use hir::source_binder; | |||
15 | 15 | ||
16 | use crate::{ | 16 | use crate::{ |
17 | db, | 17 | db, |
18 | Cancelable, FilePosition | 18 | Cancelable, FilePosition, |
19 | completion::completion_item::Completions, | ||
19 | }; | 20 | }; |
20 | 21 | ||
21 | pub use crate::completion::completion_item::{CompletionItem, InsertText}; | 22 | pub use crate::completion::completion_item::{CompletionItem, InsertText}; |
@@ -33,15 +34,15 @@ pub(crate) fn completions( | |||
33 | 34 | ||
34 | let module = ctry!(source_binder::module_from_position(db, position)?); | 35 | let module = ctry!(source_binder::module_from_position(db, position)?); |
35 | 36 | ||
36 | let mut res = Vec::new(); | 37 | let mut acc = Completions::default(); |
37 | let mut has_completions = false; | 38 | let mut has_completions = false; |
38 | // First, let's try to complete a reference to some declaration. | 39 | // First, let's try to complete a reference to some declaration. |
39 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) { | 40 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) { |
40 | has_completions = true; | 41 | has_completions = true; |
41 | reference_completion::completions(&mut res, db, &module, &file, name_ref)?; | 42 | reference_completion::completions(&mut acc, db, &module, &file, name_ref)?; |
42 | // special case, `trait T { fn foo(i_am_a_name_ref) {} }` | 43 | // special case, `trait T { fn foo(i_am_a_name_ref) {} }` |
43 | if is_node::<ast::Param>(name_ref.syntax()) { | 44 | if is_node::<ast::Param>(name_ref.syntax()) { |
44 | param_completions(&mut res, name_ref.syntax()); | 45 | param_completions(&mut acc, name_ref.syntax()); |
45 | } | 46 | } |
46 | } | 47 | } |
47 | 48 | ||
@@ -49,10 +50,14 @@ pub(crate) fn completions( | |||
49 | if let Some(name) = find_node_at_offset::<ast::Name>(file.syntax(), position.offset) { | 50 | if let Some(name) = find_node_at_offset::<ast::Name>(file.syntax(), position.offset) { |
50 | if is_node::<ast::Param>(name.syntax()) { | 51 | if is_node::<ast::Param>(name.syntax()) { |
51 | has_completions = true; | 52 | has_completions = true; |
52 | param_completions(&mut res, name.syntax()); | 53 | param_completions(&mut acc, name.syntax()); |
53 | } | 54 | } |
54 | } | 55 | } |
55 | let res = if has_completions { Some(res) } else { None }; | 56 | let res = if has_completions { |
57 | Some(acc.into()) | ||
58 | } else { | ||
59 | None | ||
60 | }; | ||
56 | Ok(res) | 61 | Ok(res) |
57 | } | 62 | } |
58 | 63 | ||
@@ -60,7 +65,7 @@ pub(crate) fn completions( | |||
60 | /// functions in a file have a `spam: &mut Spam` parameter, a completion with | 65 | /// functions in a file have a `spam: &mut Spam` parameter, a completion with |
61 | /// `spam: &mut Spam` insert text/label and `spam` lookup string will be | 66 | /// `spam: &mut Spam` insert text/label and `spam` lookup string will be |
62 | /// suggested. | 67 | /// suggested. |
63 | fn param_completions(acc: &mut Vec<CompletionItem>, ctx: SyntaxNodeRef) { | 68 | fn param_completions(acc: &mut Completions, ctx: SyntaxNodeRef) { |
64 | let mut params = FxHashMap::default(); | 69 | let mut params = FxHashMap::default(); |
65 | for node in ctx.ancestors() { | 70 | for node in ctx.ancestors() { |
66 | let _ = visitor_ctx(&mut params) | 71 | let _ = visitor_ctx(&mut params) |
diff --git a/crates/ra_analysis/src/completion/completion_item.rs b/crates/ra_analysis/src/completion/completion_item.rs index 445d6bf41..8aa9da005 100644 --- a/crates/ra_analysis/src/completion/completion_item.rs +++ b/crates/ra_analysis/src/completion/completion_item.rs | |||
@@ -53,8 +53,8 @@ pub(crate) struct Builder { | |||
53 | } | 53 | } |
54 | 54 | ||
55 | impl Builder { | 55 | impl Builder { |
56 | pub fn add_to(self, acc: &mut Vec<CompletionItem>) { | 56 | pub fn add_to(self, acc: &mut Completions) { |
57 | acc.push(self.build()) | 57 | acc.add(self.build()) |
58 | } | 58 | } |
59 | 59 | ||
60 | pub fn build(self) -> CompletionItem { | 60 | pub fn build(self) -> CompletionItem { |
@@ -81,7 +81,7 @@ impl Into<CompletionItem> for Builder { | |||
81 | } | 81 | } |
82 | 82 | ||
83 | /// Represents an in-progress set of completions being built. | 83 | /// Represents an in-progress set of completions being built. |
84 | #[derive(Debug)] | 84 | #[derive(Debug, Default)] |
85 | pub(crate) struct Completions { | 85 | pub(crate) struct Completions { |
86 | buf: Vec<CompletionItem>, | 86 | buf: Vec<CompletionItem>, |
87 | } | 87 | } |
@@ -90,6 +90,13 @@ impl Completions { | |||
90 | pub(crate) fn add(&mut self, item: impl Into<CompletionItem>) { | 90 | pub(crate) fn add(&mut self, item: impl Into<CompletionItem>) { |
91 | self.buf.push(item.into()) | 91 | self.buf.push(item.into()) |
92 | } | 92 | } |
93 | pub(crate) fn add_all<I>(&mut self, items: I) | ||
94 | where | ||
95 | I: IntoIterator, | ||
96 | I::Item: Into<CompletionItem>, | ||
97 | { | ||
98 | items.into_iter().for_each(|item| self.add(item.into())) | ||
99 | } | ||
93 | } | 100 | } |
94 | 101 | ||
95 | impl Into<Vec<CompletionItem>> for Completions { | 102 | impl Into<Vec<CompletionItem>> for Completions { |
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index f9f01a642..c578e9e8b 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs | |||
@@ -13,12 +13,12 @@ use hir::{ | |||
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | db::RootDatabase, | 15 | db::RootDatabase, |
16 | completion::CompletionItem, | 16 | completion::{CompletionItem, Completions}, |
17 | Cancelable | 17 | Cancelable |
18 | }; | 18 | }; |
19 | 19 | ||
20 | pub(super) fn completions( | 20 | pub(super) fn completions( |
21 | acc: &mut Vec<CompletionItem>, | 21 | acc: &mut Completions, |
22 | db: &RootDatabase, | 22 | db: &RootDatabase, |
23 | module: &hir::Module, | 23 | module: &hir::Module, |
24 | file: &SourceFileNode, | 24 | file: &SourceFileNode, |
@@ -117,7 +117,7 @@ fn classify_name_ref(name_ref: ast::NameRef) -> Option<NameRefKind> { | |||
117 | None | 117 | None |
118 | } | 118 | } |
119 | 119 | ||
120 | fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec<CompletionItem>) { | 120 | fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Completions) { |
121 | let mut shadowed = FxHashSet::default(); | 121 | let mut shadowed = FxHashSet::default(); |
122 | scopes | 122 | scopes |
123 | .scope_chain(name_ref.syntax()) | 123 | .scope_chain(name_ref.syntax()) |
@@ -130,7 +130,7 @@ fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec<Completi | |||
130 | } | 130 | } |
131 | 131 | ||
132 | fn complete_path( | 132 | fn complete_path( |
133 | acc: &mut Vec<CompletionItem>, | 133 | acc: &mut Completions, |
134 | db: &RootDatabase, | 134 | db: &RootDatabase, |
135 | module: &hir::Module, | 135 | module: &hir::Module, |
136 | mut path: Path, | 136 | mut path: Path, |
@@ -154,7 +154,7 @@ fn complete_path( | |||
154 | Ok(()) | 154 | Ok(()) |
155 | } | 155 | } |
156 | 156 | ||
157 | fn complete_mod_item_snippets(acc: &mut Vec<CompletionItem>) { | 157 | fn complete_mod_item_snippets(acc: &mut Completions) { |
158 | CompletionItem::new("Test function") | 158 | CompletionItem::new("Test function") |
159 | .lookup_by("tfn") | 159 | .lookup_by("tfn") |
160 | .snippet( | 160 | .snippet( |
@@ -174,26 +174,26 @@ fn complete_expr_keywords( | |||
174 | file: &SourceFileNode, | 174 | file: &SourceFileNode, |
175 | fn_def: ast::FnDef, | 175 | fn_def: ast::FnDef, |
176 | name_ref: ast::NameRef, | 176 | name_ref: ast::NameRef, |
177 | acc: &mut Vec<CompletionItem>, | 177 | acc: &mut Completions, |
178 | ) { | 178 | ) { |
179 | acc.push(keyword("if", "if $0 {}")); | 179 | acc.add(keyword("if", "if $0 {}")); |
180 | acc.push(keyword("match", "match $0 {}")); | 180 | acc.add(keyword("match", "match $0 {}")); |
181 | acc.push(keyword("while", "while $0 {}")); | 181 | acc.add(keyword("while", "while $0 {}")); |
182 | acc.push(keyword("loop", "loop {$0}")); | 182 | acc.add(keyword("loop", "loop {$0}")); |
183 | 183 | ||
184 | if let Some(off) = name_ref.syntax().range().start().checked_sub(2.into()) { | 184 | if let Some(off) = name_ref.syntax().range().start().checked_sub(2.into()) { |
185 | if let Some(if_expr) = find_node_at_offset::<ast::IfExpr>(file.syntax(), off) { | 185 | if let Some(if_expr) = find_node_at_offset::<ast::IfExpr>(file.syntax(), off) { |
186 | if if_expr.syntax().range().end() < name_ref.syntax().range().start() { | 186 | if if_expr.syntax().range().end() < name_ref.syntax().range().start() { |
187 | acc.push(keyword("else", "else {$0}")); | 187 | acc.add(keyword("else", "else {$0}")); |
188 | acc.push(keyword("else if", "else if $0 {}")); | 188 | acc.add(keyword("else if", "else if $0 {}")); |
189 | } | 189 | } |
190 | } | 190 | } |
191 | } | 191 | } |
192 | if is_in_loop_body(name_ref) { | 192 | if is_in_loop_body(name_ref) { |
193 | acc.push(keyword("continue", "continue")); | 193 | acc.add(keyword("continue", "continue")); |
194 | acc.push(keyword("break", "break")); | 194 | acc.add(keyword("break", "break")); |
195 | } | 195 | } |
196 | acc.extend(complete_return(fn_def, name_ref)); | 196 | acc.add_all(complete_return(fn_def, name_ref)); |
197 | } | 197 | } |
198 | 198 | ||
199 | fn is_in_loop_body(name_ref: ast::NameRef) -> bool { | 199 | fn is_in_loop_body(name_ref: ast::NameRef) -> bool { |
@@ -252,7 +252,7 @@ fn keyword(kw: &str, snippet: &str) -> CompletionItem { | |||
252 | CompletionItem::new(kw).snippet(snippet).build() | 252 | CompletionItem::new(kw).snippet(snippet).build() |
253 | } | 253 | } |
254 | 254 | ||
255 | fn complete_expr_snippets(acc: &mut Vec<CompletionItem>) { | 255 | fn complete_expr_snippets(acc: &mut Completions) { |
256 | CompletionItem::new("pd") | 256 | CompletionItem::new("pd") |
257 | .snippet("eprintln!(\"$0 = {:?}\", $0);") | 257 | .snippet("eprintln!(\"$0 = {:?}\", $0);") |
258 | .add_to(acc); | 258 | .add_to(acc); |