diff options
author | Mikhail Rakhmanov <[email protected]> | 2020-06-13 09:43:39 +0100 |
---|---|---|
committer | Mikhail Rakhmanov <[email protected]> | 2020-06-13 09:43:39 +0100 |
commit | 912f38200fb6c8c6cea750a84c04de810992dec7 (patch) | |
tree | 7786c87c7fbfeaaffa075bb269de63ffdf712e5d /crates/ra_ide/src | |
parent | 16bbf4ab7f132e6e5e5318dccdef9a5d71afdd7f (diff) |
Add keywords completions on source file position
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/completion/complete_keyword.rs | 115 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/completion_context.rs | 8 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/patterns.rs | 22 |
3 files changed, 124 insertions, 21 deletions
diff --git a/crates/ra_ide/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs index 025097e49..d016f0c7c 100644 --- a/crates/ra_ide/src/completion/complete_keyword.rs +++ b/crates/ra_ide/src/completion/complete_keyword.rs | |||
@@ -66,48 +66,83 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
66 | return; | 66 | return; |
67 | } | 67 | } |
68 | if ctx.unsafe_is_prev { | 68 | if ctx.unsafe_is_prev { |
69 | add_keyword(ctx, acc, "fn", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent); | 69 | add_keyword( |
70 | ctx, | ||
71 | acc, | ||
72 | "fn", | ||
73 | "fn $0() {}", | ||
74 | ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent, | ||
75 | ); | ||
70 | add_keyword( | 76 | add_keyword( |
71 | ctx, | 77 | ctx, |
72 | acc, | 78 | acc, |
73 | "trait", | 79 | "trait", |
74 | "trait $0 {}", | 80 | "trait $0 {}", |
75 | (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, | 81 | (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) |
82 | || ctx.block_expr_parent, | ||
76 | ); | 83 | ); |
77 | add_keyword( | 84 | add_keyword( |
78 | ctx, | 85 | ctx, |
79 | acc, | 86 | acc, |
80 | "impl", | 87 | "impl", |
81 | "impl $0 {}", | 88 | "impl $0 {}", |
82 | (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, | 89 | (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) |
90 | || ctx.block_expr_parent, | ||
83 | ); | 91 | ); |
84 | return; | 92 | return; |
85 | } | 93 | } |
86 | add_keyword(ctx, acc, "fn", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent); | 94 | add_keyword( |
95 | ctx, | ||
96 | acc, | ||
97 | "fn", | ||
98 | "fn $0() {}", | ||
99 | ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent, | ||
100 | ); | ||
87 | add_keyword( | 101 | add_keyword( |
88 | ctx, | 102 | ctx, |
89 | acc, | 103 | acc, |
90 | "use", | 104 | "use", |
91 | "use ", | 105 | "use ", |
92 | (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, | 106 | (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) |
107 | || ctx.block_expr_parent, | ||
93 | ); | 108 | ); |
94 | add_keyword( | 109 | add_keyword( |
95 | ctx, | 110 | ctx, |
96 | acc, | 111 | acc, |
97 | "impl", | 112 | "impl", |
98 | "impl $0 {}", | 113 | "impl $0 {}", |
99 | (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, | 114 | (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) |
115 | || ctx.block_expr_parent, | ||
100 | ); | 116 | ); |
101 | add_keyword( | 117 | add_keyword( |
102 | ctx, | 118 | ctx, |
103 | acc, | 119 | acc, |
104 | "trait", | 120 | "trait", |
105 | "trait $0 {}", | 121 | "trait $0 {}", |
106 | (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, | 122 | (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) |
123 | || ctx.block_expr_parent, | ||
124 | ); | ||
125 | add_keyword( | ||
126 | ctx, | ||
127 | acc, | ||
128 | "enum", | ||
129 | "enum $0 {}", | ||
130 | ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent, | ||
131 | ); | ||
132 | add_keyword( | ||
133 | ctx, | ||
134 | acc, | ||
135 | "struct", | ||
136 | "struct $0 {}", | ||
137 | ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent, | ||
138 | ); | ||
139 | add_keyword( | ||
140 | ctx, | ||
141 | acc, | ||
142 | "union", | ||
143 | "union $0 {}", | ||
144 | ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent, | ||
107 | ); | 145 | ); |
108 | add_keyword(ctx, acc, "enum", "enum $0 {}", ctx.is_new_item && !has_trait_or_impl_parent); | ||
109 | add_keyword(ctx, acc, "struct", "struct $0 {}", ctx.is_new_item && !has_trait_or_impl_parent); | ||
110 | add_keyword(ctx, acc, "union", "union $0 {}", ctx.is_new_item && !has_trait_or_impl_parent); | ||
111 | add_keyword(ctx, acc, "match", "match $0 {}", ctx.block_expr_parent || ctx.is_match_arm); | 146 | add_keyword(ctx, acc, "match", "match $0 {}", ctx.block_expr_parent || ctx.is_match_arm); |
112 | add_keyword(ctx, acc, "loop", "loop {$0}", ctx.block_expr_parent || ctx.is_match_arm); | 147 | add_keyword(ctx, acc, "loop", "loop {$0}", ctx.block_expr_parent || ctx.is_match_arm); |
113 | add_keyword(ctx, acc, "while", "while $0 {}", ctx.block_expr_parent); | 148 | add_keyword(ctx, acc, "while", "while $0 {}", ctx.block_expr_parent); |
@@ -127,37 +162,58 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
127 | acc, | 162 | acc, |
128 | "mod", | 163 | "mod", |
129 | "mod $0 {}", | 164 | "mod $0 {}", |
130 | (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, | 165 | (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) |
166 | || ctx.block_expr_parent, | ||
131 | ); | 167 | ); |
132 | add_keyword(ctx, acc, "mut", "mut ", ctx.bind_pat_parent || ctx.ref_pat_parent); | 168 | add_keyword(ctx, acc, "mut", "mut ", ctx.bind_pat_parent || ctx.ref_pat_parent); |
133 | add_keyword(ctx, acc, "const", "const ", ctx.is_new_item || ctx.block_expr_parent); | 169 | add_keyword( |
134 | add_keyword(ctx, acc, "type", "type ", ctx.is_new_item || ctx.block_expr_parent); | 170 | ctx, |
171 | acc, | ||
172 | "const", | ||
173 | "const ", | ||
174 | ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent, | ||
175 | ); | ||
176 | add_keyword( | ||
177 | ctx, | ||
178 | acc, | ||
179 | "type", | ||
180 | "type ", | ||
181 | ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent, | ||
182 | ); | ||
135 | add_keyword( | 183 | add_keyword( |
136 | ctx, | 184 | ctx, |
137 | acc, | 185 | acc, |
138 | "static", | 186 | "static", |
139 | "static ", | 187 | "static ", |
140 | (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, | 188 | (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) |
189 | || ctx.block_expr_parent, | ||
141 | ); | 190 | ); |
142 | add_keyword( | 191 | add_keyword( |
143 | ctx, | 192 | ctx, |
144 | acc, | 193 | acc, |
145 | "extern", | 194 | "extern", |
146 | "extern ", | 195 | "extern ", |
147 | (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, | 196 | (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) |
197 | || ctx.block_expr_parent, | ||
148 | ); | 198 | ); |
149 | add_keyword( | 199 | add_keyword( |
150 | ctx, | 200 | ctx, |
151 | acc, | 201 | acc, |
152 | "unsafe", | 202 | "unsafe", |
153 | "unsafe ", | 203 | "unsafe ", |
154 | ctx.is_new_item || ctx.block_expr_parent || ctx.is_match_arm, | 204 | ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent || ctx.is_match_arm, |
155 | ); | 205 | ); |
156 | add_keyword(ctx, acc, "continue", "continue;", ctx.in_loop_body && ctx.can_be_stmt); | 206 | add_keyword(ctx, acc, "continue", "continue;", ctx.in_loop_body && ctx.can_be_stmt); |
157 | add_keyword(ctx, acc, "break", "break;", ctx.in_loop_body && ctx.can_be_stmt); | 207 | add_keyword(ctx, acc, "break", "break;", ctx.in_loop_body && ctx.can_be_stmt); |
158 | add_keyword(ctx, acc, "continue", "continue", ctx.in_loop_body && !ctx.can_be_stmt); | 208 | add_keyword(ctx, acc, "continue", "continue", ctx.in_loop_body && !ctx.can_be_stmt); |
159 | add_keyword(ctx, acc, "break", "break", ctx.in_loop_body && !ctx.can_be_stmt); | 209 | add_keyword(ctx, acc, "break", "break", ctx.in_loop_body && !ctx.can_be_stmt); |
160 | add_keyword(ctx, acc, "pub", "pub ", ctx.is_new_item && !ctx.has_trait_parent); | 210 | add_keyword( |
211 | ctx, | ||
212 | acc, | ||
213 | "pub", | ||
214 | "pub ", | ||
215 | ctx.has_item_list_or_source_file_parent && !ctx.has_trait_parent, | ||
216 | ); | ||
161 | 217 | ||
162 | if !ctx.is_trivial_path { | 218 | if !ctx.is_trivial_path { |
163 | return; | 219 | return; |
@@ -227,6 +283,31 @@ mod tests { | |||
227 | } | 283 | } |
228 | 284 | ||
229 | #[test] | 285 | #[test] |
286 | fn test_keywords_at_source_file_level() { | ||
287 | assert_debug_snapshot!( | ||
288 | get_keyword_completions(r"m<|>"), | ||
289 | @r###" | ||
290 | [ | ||
291 | "kw const", | ||
292 | "kw enum", | ||
293 | "kw extern", | ||
294 | "kw fn", | ||
295 | "kw impl", | ||
296 | "kw mod", | ||
297 | "kw pub", | ||
298 | "kw static", | ||
299 | "kw struct", | ||
300 | "kw trait", | ||
301 | "kw type", | ||
302 | "kw union", | ||
303 | "kw unsafe", | ||
304 | "kw use", | ||
305 | ] | ||
306 | "### | ||
307 | ); | ||
308 | } | ||
309 | |||
310 | #[test] | ||
230 | fn test_keywords_in_function() { | 311 | fn test_keywords_in_function() { |
231 | assert_debug_snapshot!( | 312 | assert_debug_snapshot!( |
232 | get_keyword_completions(r"fn quux() { <|> }"), | 313 | get_keyword_completions(r"fn quux() { <|> }"), |
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 2f96861ca..9f4c582d0 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs | |||
@@ -13,8 +13,8 @@ use ra_text_edit::Indel; | |||
13 | 13 | ||
14 | use super::patterns::{ | 14 | use super::patterns::{ |
15 | has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_impl_parent, | 15 | has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_impl_parent, |
16 | has_ref_parent, has_trait_as_prev_sibling, has_trait_parent, if_is_prev, is_in_loop_body, | 16 | has_item_list_or_source_file_parent, has_ref_parent, has_trait_as_prev_sibling, |
17 | is_match_arm, unsafe_is_prev, | 17 | has_trait_parent, if_is_prev, is_in_loop_body, is_match_arm, unsafe_is_prev, |
18 | }; | 18 | }; |
19 | use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition}; | 19 | use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition}; |
20 | use test_utils::mark; | 20 | use test_utils::mark; |
@@ -76,6 +76,7 @@ pub(crate) struct CompletionContext<'a> { | |||
76 | pub(super) trait_as_prev_sibling: bool, | 76 | pub(super) trait_as_prev_sibling: bool, |
77 | pub(super) impl_as_prev_sibling: bool, | 77 | pub(super) impl_as_prev_sibling: bool, |
78 | pub(super) is_match_arm: bool, | 78 | pub(super) is_match_arm: bool, |
79 | pub(super) has_item_list_or_source_file_parent: bool, | ||
79 | } | 80 | } |
80 | 81 | ||
81 | impl<'a> CompletionContext<'a> { | 82 | impl<'a> CompletionContext<'a> { |
@@ -145,6 +146,7 @@ impl<'a> CompletionContext<'a> { | |||
145 | impl_as_prev_sibling: false, | 146 | impl_as_prev_sibling: false, |
146 | if_is_prev: false, | 147 | if_is_prev: false, |
147 | is_match_arm: false, | 148 | is_match_arm: false, |
149 | has_item_list_or_source_file_parent: false, | ||
148 | }; | 150 | }; |
149 | 151 | ||
150 | let mut original_file = original_file.syntax().clone(); | 152 | let mut original_file = original_file.syntax().clone(); |
@@ -229,6 +231,8 @@ impl<'a> CompletionContext<'a> { | |||
229 | self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone()); | 231 | self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone()); |
230 | self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone()); | 232 | self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone()); |
231 | self.is_match_arm = is_match_arm(syntax_element.clone()); | 233 | self.is_match_arm = is_match_arm(syntax_element.clone()); |
234 | self.has_item_list_or_source_file_parent = | ||
235 | has_item_list_or_source_file_parent(syntax_element.clone()); | ||
232 | } | 236 | } |
233 | 237 | ||
234 | fn fill( | 238 | fn fill( |
diff --git a/crates/ra_ide/src/completion/patterns.rs b/crates/ra_ide/src/completion/patterns.rs index 464032cb4..fdcd3faa5 100644 --- a/crates/ra_ide/src/completion/patterns.rs +++ b/crates/ra_ide/src/completion/patterns.rs | |||
@@ -38,6 +38,14 @@ pub(crate) fn has_ref_parent(element: SyntaxElement) -> bool { | |||
38 | .is_some() | 38 | .is_some() |
39 | } | 39 | } |
40 | 40 | ||
41 | pub(crate) fn has_item_list_or_source_file_parent(element: SyntaxElement) -> bool { | ||
42 | let ancestor = not_same_range_ancestor(element); | ||
43 | if !ancestor.is_some() { | ||
44 | return true; | ||
45 | } | ||
46 | ancestor.filter(|it| it.kind() == SOURCE_FILE || it.kind() == ITEM_LIST).is_some() | ||
47 | } | ||
48 | |||
41 | pub(crate) fn is_match_arm(element: SyntaxElement) -> bool { | 49 | pub(crate) fn is_match_arm(element: SyntaxElement) -> bool { |
42 | not_same_range_ancestor(element.clone()).filter(|it| it.kind() == MATCH_ARM).is_some() | 50 | not_same_range_ancestor(element.clone()).filter(|it| it.kind() == MATCH_ARM).is_some() |
43 | && previous_sibling_or_ancestor_sibling(element) | 51 | && previous_sibling_or_ancestor_sibling(element) |
@@ -139,8 +147,8 @@ fn previous_sibling_or_ancestor_sibling(element: SyntaxElement) -> Option<Syntax | |||
139 | mod tests { | 147 | mod tests { |
140 | use super::{ | 148 | use super::{ |
141 | has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_impl_parent, | 149 | has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_impl_parent, |
142 | has_ref_parent, has_trait_as_prev_sibling, has_trait_parent, if_is_prev, is_match_arm, | 150 | has_item_list_or_source_file_parent, has_ref_parent, has_trait_as_prev_sibling, |
143 | unsafe_is_prev, | 151 | has_trait_parent, if_is_prev, is_match_arm, unsafe_is_prev, |
144 | }; | 152 | }; |
145 | use crate::completion::test_utils::check_pattern_is_applicable; | 153 | use crate::completion::test_utils::check_pattern_is_applicable; |
146 | 154 | ||
@@ -203,4 +211,14 @@ mod tests { | |||
203 | fn test_is_match_arm() { | 211 | fn test_is_match_arm() { |
204 | check_pattern_is_applicable(r"fn my_fn() { match () { () => m<|> } }", is_match_arm); | 212 | check_pattern_is_applicable(r"fn my_fn() { match () { () => m<|> } }", is_match_arm); |
205 | } | 213 | } |
214 | |||
215 | #[test] | ||
216 | fn test_has_source_file_parent() { | ||
217 | check_pattern_is_applicable(r"i<|>", has_item_list_or_source_file_parent); | ||
218 | } | ||
219 | |||
220 | #[test] | ||
221 | fn test_has_item_list_parent() { | ||
222 | check_pattern_is_applicable(r"impl { f<|> }", has_item_list_or_source_file_parent); | ||
223 | } | ||
206 | } | 224 | } |