diff options
author | gfreezy <[email protected]> | 2019-01-19 14:02:50 +0000 |
---|---|---|
committer | gfreezy <[email protected]> | 2019-01-19 14:02:50 +0000 |
commit | d08e81cdd818dd3378c292767e15a38e6bbc6f6c (patch) | |
tree | e07b3363f21912ca7aaca4ae1dce482c0bcd6f85 /crates/ra_ide_api/src/completion/complete_keyword.rs | |
parent | fa43ef30f4f96fc8e4ea1f9c4492bcb07b3335ca (diff) |
refactor completions to use TextEdit instead of InsertText
Diffstat (limited to 'crates/ra_ide_api/src/completion/complete_keyword.rs')
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_keyword.rs | 164 |
1 files changed, 46 insertions, 118 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_keyword.rs b/crates/ra_ide_api/src/completion/complete_keyword.rs index d350f06ce..3fbf36313 100644 --- a/crates/ra_ide_api/src/completion/complete_keyword.rs +++ b/crates/ra_ide_api/src/completion/complete_keyword.rs | |||
@@ -11,36 +11,33 @@ pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC | |||
11 | // complete keyword "crate" in use stmt | 11 | // complete keyword "crate" in use stmt |
12 | match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) { | 12 | match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) { |
13 | (Some(_), None) => { | 13 | (Some(_), None) => { |
14 | CompletionItem::new(CompletionKind::Keyword, "crate") | 14 | CompletionItem::new(CompletionKind::Keyword, ctx, "crate") |
15 | .kind(CompletionItemKind::Keyword) | 15 | .kind(CompletionItemKind::Keyword) |
16 | .lookup_by("crate") | 16 | .insert_text("crate::") |
17 | .snippet("crate::") | ||
18 | .add_to(acc); | 17 | .add_to(acc); |
19 | CompletionItem::new(CompletionKind::Keyword, "self") | 18 | CompletionItem::new(CompletionKind::Keyword, ctx, "self") |
20 | .kind(CompletionItemKind::Keyword) | 19 | .kind(CompletionItemKind::Keyword) |
21 | .lookup_by("self") | ||
22 | .add_to(acc); | 20 | .add_to(acc); |
23 | CompletionItem::new(CompletionKind::Keyword, "super") | 21 | CompletionItem::new(CompletionKind::Keyword, ctx, "super") |
24 | .kind(CompletionItemKind::Keyword) | 22 | .kind(CompletionItemKind::Keyword) |
25 | .lookup_by("super") | 23 | .insert_text("super::") |
26 | .add_to(acc); | 24 | .add_to(acc); |
27 | } | 25 | } |
28 | (Some(_), Some(_)) => { | 26 | (Some(_), Some(_)) => { |
29 | CompletionItem::new(CompletionKind::Keyword, "self") | 27 | CompletionItem::new(CompletionKind::Keyword, ctx, "self") |
30 | .kind(CompletionItemKind::Keyword) | 28 | .kind(CompletionItemKind::Keyword) |
31 | .lookup_by("self") | ||
32 | .add_to(acc); | 29 | .add_to(acc); |
33 | CompletionItem::new(CompletionKind::Keyword, "super") | 30 | CompletionItem::new(CompletionKind::Keyword, ctx, "super") |
34 | .kind(CompletionItemKind::Keyword) | 31 | .kind(CompletionItemKind::Keyword) |
35 | .lookup_by("super") | 32 | .insert_text("super::") |
36 | .add_to(acc); | 33 | .add_to(acc); |
37 | } | 34 | } |
38 | _ => {} | 35 | _ => {} |
39 | } | 36 | } |
40 | } | 37 | } |
41 | 38 | ||
42 | fn keyword(kw: &str, snippet: &str) -> CompletionItem { | 39 | fn keyword(ctx: &CompletionContext, kw: &str, snippet: &str) -> CompletionItem { |
43 | CompletionItem::new(CompletionKind::Keyword, kw) | 40 | CompletionItem::new(CompletionKind::Keyword, ctx, kw) |
44 | .kind(CompletionItemKind::Keyword) | 41 | .kind(CompletionItemKind::Keyword) |
45 | .snippet(snippet) | 42 | .snippet(snippet) |
46 | .build() | 43 | .build() |
@@ -55,25 +52,25 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
55 | Some(it) => it, | 52 | Some(it) => it, |
56 | None => return, | 53 | None => return, |
57 | }; | 54 | }; |
58 | acc.add(keyword("if", "if $0 {}")); | 55 | acc.add(keyword(ctx, "if", "if $0 {}")); |
59 | acc.add(keyword("match", "match $0 {}")); | 56 | acc.add(keyword(ctx, "match", "match $0 {}")); |
60 | acc.add(keyword("while", "while $0 {}")); | 57 | acc.add(keyword(ctx, "while", "while $0 {}")); |
61 | acc.add(keyword("loop", "loop {$0}")); | 58 | acc.add(keyword(ctx, "loop", "loop {$0}")); |
62 | 59 | ||
63 | if ctx.after_if { | 60 | if ctx.after_if { |
64 | acc.add(keyword("else", "else {$0}")); | 61 | acc.add(keyword(ctx, "else", "else {$0}")); |
65 | acc.add(keyword("else if", "else if $0 {}")); | 62 | acc.add(keyword(ctx, "else if", "else if $0 {}")); |
66 | } | 63 | } |
67 | if is_in_loop_body(ctx.leaf) { | 64 | if is_in_loop_body(ctx.leaf) { |
68 | if ctx.can_be_stmt { | 65 | if ctx.can_be_stmt { |
69 | acc.add(keyword("continue", "continue;")); | 66 | acc.add(keyword(ctx, "continue", "continue;")); |
70 | acc.add(keyword("break", "break;")); | 67 | acc.add(keyword(ctx, "break", "break;")); |
71 | } else { | 68 | } else { |
72 | acc.add(keyword("continue", "continue")); | 69 | acc.add(keyword(ctx, "continue", "continue")); |
73 | acc.add(keyword("break", "break")); | 70 | acc.add(keyword(ctx, "break", "break")); |
74 | } | 71 | } |
75 | } | 72 | } |
76 | acc.add_all(complete_return(fn_def, ctx.can_be_stmt)); | 73 | acc.add_all(complete_return(ctx, fn_def, ctx.can_be_stmt)); |
77 | } | 74 | } |
78 | 75 | ||
79 | fn is_in_loop_body(leaf: &SyntaxNode) -> bool { | 76 | fn is_in_loop_body(leaf: &SyntaxNode) -> bool { |
@@ -95,78 +92,69 @@ fn is_in_loop_body(leaf: &SyntaxNode) -> bool { | |||
95 | false | 92 | false |
96 | } | 93 | } |
97 | 94 | ||
98 | fn complete_return(fn_def: &ast::FnDef, can_be_stmt: bool) -> Option<CompletionItem> { | 95 | fn complete_return( |
96 | ctx: &CompletionContext, | ||
97 | fn_def: &ast::FnDef, | ||
98 | can_be_stmt: bool, | ||
99 | ) -> Option<CompletionItem> { | ||
99 | let snip = match (can_be_stmt, fn_def.ret_type().is_some()) { | 100 | let snip = match (can_be_stmt, fn_def.ret_type().is_some()) { |
100 | (true, true) => "return $0;", | 101 | (true, true) => "return $0;", |
101 | (true, false) => "return;", | 102 | (true, false) => "return;", |
102 | (false, true) => "return $0", | 103 | (false, true) => "return $0", |
103 | (false, false) => "return", | 104 | (false, false) => "return", |
104 | }; | 105 | }; |
105 | Some(keyword("return", snip)) | 106 | Some(keyword(ctx, "return", snip)) |
106 | } | 107 | } |
107 | 108 | ||
108 | #[cfg(test)] | 109 | #[cfg(test)] |
109 | mod tests { | 110 | mod tests { |
110 | use crate::completion::{CompletionKind, check_completion}; | 111 | use crate::completion::CompletionKind; |
111 | fn check_keyword_completion(code: &str, expected_completions: &str) { | 112 | use crate::completion::completion_item::check_completion; |
112 | check_completion(code, expected_completions, CompletionKind::Keyword); | 113 | |
114 | fn check_keyword_completion(name: &str, code: &str) { | ||
115 | check_completion(name, code, CompletionKind::Keyword); | ||
113 | } | 116 | } |
114 | 117 | ||
115 | #[test] | 118 | #[test] |
116 | fn completes_keywords_in_use_stmt() { | 119 | fn completes_keywords_in_use_stmt() { |
117 | check_keyword_completion( | 120 | check_keyword_completion( |
121 | "keywords_in_use_stmt1", | ||
118 | r" | 122 | r" |
119 | use <|> | 123 | use <|> |
120 | ", | 124 | ", |
121 | r#" | ||
122 | crate "crate" "crate::" | ||
123 | self "self" | ||
124 | super "super" | ||
125 | "#, | ||
126 | ); | 125 | ); |
127 | 126 | ||
128 | check_keyword_completion( | 127 | check_keyword_completion( |
128 | "keywords_in_use_stmt2", | ||
129 | r" | 129 | r" |
130 | use a::<|> | 130 | use a::<|> |
131 | ", | 131 | ", |
132 | r#" | ||
133 | self "self" | ||
134 | super "super" | ||
135 | "#, | ||
136 | ); | 132 | ); |
137 | 133 | ||
138 | check_keyword_completion( | 134 | check_keyword_completion( |
135 | "keywords_in_use_stmt3", | ||
139 | r" | 136 | r" |
140 | use a::{b, <|>} | 137 | use a::{b, <|>} |
141 | ", | 138 | ", |
142 | r#" | ||
143 | self "self" | ||
144 | super "super" | ||
145 | "#, | ||
146 | ); | 139 | ); |
147 | } | 140 | } |
148 | 141 | ||
149 | #[test] | 142 | #[test] |
150 | fn completes_various_keywords_in_function() { | 143 | fn completes_various_keywords_in_function() { |
151 | check_keyword_completion( | 144 | check_keyword_completion( |
145 | "keywords_in_function1", | ||
152 | r" | 146 | r" |
153 | fn quux() { | 147 | fn quux() { |
154 | <|> | 148 | <|> |
155 | } | 149 | } |
156 | ", | 150 | ", |
157 | r#" | ||
158 | if "if $0 {}" | ||
159 | match "match $0 {}" | ||
160 | while "while $0 {}" | ||
161 | loop "loop {$0}" | ||
162 | return "return;" | ||
163 | "#, | ||
164 | ); | 151 | ); |
165 | } | 152 | } |
166 | 153 | ||
167 | #[test] | 154 | #[test] |
168 | fn completes_else_after_if() { | 155 | fn completes_else_after_if() { |
169 | check_keyword_completion( | 156 | check_keyword_completion( |
157 | "keywords_in_function2", | ||
170 | r" | 158 | r" |
171 | fn quux() { | 159 | fn quux() { |
172 | if true { | 160 | if true { |
@@ -174,55 +162,35 @@ mod tests { | |||
174 | } <|> | 162 | } <|> |
175 | } | 163 | } |
176 | ", | 164 | ", |
177 | r#" | ||
178 | if "if $0 {}" | ||
179 | match "match $0 {}" | ||
180 | while "while $0 {}" | ||
181 | loop "loop {$0}" | ||
182 | else "else {$0}" | ||
183 | else if "else if $0 {}" | ||
184 | return "return;" | ||
185 | "#, | ||
186 | ); | 165 | ); |
187 | } | 166 | } |
188 | 167 | ||
189 | #[test] | 168 | #[test] |
190 | fn test_completion_return_value() { | 169 | fn test_completion_return_value() { |
191 | check_keyword_completion( | 170 | check_keyword_completion( |
171 | "keywords_in_function3", | ||
192 | r" | 172 | r" |
193 | fn quux() -> i32 { | 173 | fn quux() -> i32 { |
194 | <|> | 174 | <|> |
195 | 92 | 175 | 92 |
196 | } | 176 | } |
197 | ", | 177 | ", |
198 | r#" | ||
199 | if "if $0 {}" | ||
200 | match "match $0 {}" | ||
201 | while "while $0 {}" | ||
202 | loop "loop {$0}" | ||
203 | return "return $0;" | ||
204 | "#, | ||
205 | ); | 178 | ); |
206 | check_keyword_completion( | 179 | check_keyword_completion( |
180 | "keywords_in_function4", | ||
207 | r" | 181 | r" |
208 | fn quux() { | 182 | fn quux() { |
209 | <|> | 183 | <|> |
210 | 92 | 184 | 92 |
211 | } | 185 | } |
212 | ", | 186 | ", |
213 | r#" | ||
214 | if "if $0 {}" | ||
215 | match "match $0 {}" | ||
216 | while "while $0 {}" | ||
217 | loop "loop {$0}" | ||
218 | return "return;" | ||
219 | "#, | ||
220 | ); | 187 | ); |
221 | } | 188 | } |
222 | 189 | ||
223 | #[test] | 190 | #[test] |
224 | fn dont_add_semi_after_return_if_not_a_statement() { | 191 | fn dont_add_semi_after_return_if_not_a_statement() { |
225 | check_keyword_completion( | 192 | check_keyword_completion( |
193 | "dont_add_semi_after_return_if_not_a_statement", | ||
226 | r" | 194 | r" |
227 | fn quux() -> i32 { | 195 | fn quux() -> i32 { |
228 | match () { | 196 | match () { |
@@ -230,19 +198,13 @@ mod tests { | |||
230 | } | 198 | } |
231 | } | 199 | } |
232 | ", | 200 | ", |
233 | r#" | ||
234 | if "if $0 {}" | ||
235 | match "match $0 {}" | ||
236 | while "while $0 {}" | ||
237 | loop "loop {$0}" | ||
238 | return "return $0" | ||
239 | "#, | ||
240 | ); | 201 | ); |
241 | } | 202 | } |
242 | 203 | ||
243 | #[test] | 204 | #[test] |
244 | fn last_return_in_block_has_semi() { | 205 | fn last_return_in_block_has_semi() { |
245 | check_keyword_completion( | 206 | check_keyword_completion( |
207 | "last_return_in_block_has_semi1", | ||
246 | r" | 208 | r" |
247 | fn quux() -> i32 { | 209 | fn quux() -> i32 { |
248 | if condition { | 210 | if condition { |
@@ -250,15 +212,9 @@ mod tests { | |||
250 | } | 212 | } |
251 | } | 213 | } |
252 | ", | 214 | ", |
253 | r#" | ||
254 | if "if $0 {}" | ||
255 | match "match $0 {}" | ||
256 | while "while $0 {}" | ||
257 | loop "loop {$0}" | ||
258 | return "return $0;" | ||
259 | "#, | ||
260 | ); | 215 | ); |
261 | check_keyword_completion( | 216 | check_keyword_completion( |
217 | "last_return_in_block_has_semi2", | ||
262 | r" | 218 | r" |
263 | fn quux() -> i32 { | 219 | fn quux() -> i32 { |
264 | if condition { | 220 | if condition { |
@@ -268,54 +224,35 @@ mod tests { | |||
268 | x | 224 | x |
269 | } | 225 | } |
270 | ", | 226 | ", |
271 | r#" | ||
272 | if "if $0 {}" | ||
273 | match "match $0 {}" | ||
274 | while "while $0 {}" | ||
275 | loop "loop {$0}" | ||
276 | return "return $0;" | ||
277 | "#, | ||
278 | ); | 227 | ); |
279 | } | 228 | } |
280 | 229 | ||
281 | #[test] | 230 | #[test] |
282 | fn completes_break_and_continue_in_loops() { | 231 | fn completes_break_and_continue_in_loops() { |
283 | check_keyword_completion( | 232 | check_keyword_completion( |
233 | "completes_break_and_continue_in_loops1", | ||
284 | r" | 234 | r" |
285 | fn quux() -> i32 { | 235 | fn quux() -> i32 { |
286 | loop { <|> } | 236 | loop { <|> } |
287 | } | 237 | } |
288 | ", | 238 | ", |
289 | r#" | ||
290 | if "if $0 {}" | ||
291 | match "match $0 {}" | ||
292 | while "while $0 {}" | ||
293 | loop "loop {$0}" | ||
294 | continue "continue;" | ||
295 | break "break;" | ||
296 | return "return $0;" | ||
297 | "#, | ||
298 | ); | 239 | ); |
240 | |||
299 | // No completion: lambda isolates control flow | 241 | // No completion: lambda isolates control flow |
300 | check_keyword_completion( | 242 | check_keyword_completion( |
243 | "completes_break_and_continue_in_loops2", | ||
301 | r" | 244 | r" |
302 | fn quux() -> i32 { | 245 | fn quux() -> i32 { |
303 | loop { || { <|> } } | 246 | loop { || { <|> } } |
304 | } | 247 | } |
305 | ", | 248 | ", |
306 | r#" | ||
307 | if "if $0 {}" | ||
308 | match "match $0 {}" | ||
309 | while "while $0 {}" | ||
310 | loop "loop {$0}" | ||
311 | return "return $0;" | ||
312 | "#, | ||
313 | ); | 249 | ); |
314 | } | 250 | } |
315 | 251 | ||
316 | #[test] | 252 | #[test] |
317 | fn no_semi_after_break_continue_in_expr() { | 253 | fn no_semi_after_break_continue_in_expr() { |
318 | check_keyword_completion( | 254 | check_keyword_completion( |
255 | "no_semi_after_break_continue_in_expr", | ||
319 | r" | 256 | r" |
320 | fn f() { | 257 | fn f() { |
321 | loop { | 258 | loop { |
@@ -325,15 +262,6 @@ mod tests { | |||
325 | } | 262 | } |
326 | } | 263 | } |
327 | ", | 264 | ", |
328 | r#" | ||
329 | if "if $0 {}" | ||
330 | match "match $0 {}" | ||
331 | while "while $0 {}" | ||
332 | loop "loop {$0}" | ||
333 | continue "continue" | ||
334 | break "break" | ||
335 | return "return" | ||
336 | "#, | ||
337 | ) | 265 | ) |
338 | } | 266 | } |
339 | } | 267 | } |