diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-28 22:21:37 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-28 22:21:37 +0100 |
commit | 7869b01b702d1f12acb03ac131b6eb90ad82e9bb (patch) | |
tree | e6d76df5212db7589ef8dc6583b32d6c64871a33 /crates/ide_completion/src/completions/keyword.rs | |
parent | d5f7b2e52a41a7d3b841f4d0e2225eb703f6a50a (diff) | |
parent | e42c448077ca2b7675320da3c5294bf4bebaedeb (diff) |
Merge #9041
9041: internal: Implement prev sibling determination for `CompletionContext ` r=Veykril a=Veykril
bors r+
Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/ide_completion/src/completions/keyword.rs')
-rw-r--r-- | crates/ide_completion/src/completions/keyword.rs | 192 |
1 files changed, 94 insertions, 98 deletions
diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index c9673df85..e71a04b6e 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs | |||
@@ -48,91 +48,92 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
48 | cov_mark::hit!(no_keyword_completion_in_record_lit); | 48 | cov_mark::hit!(no_keyword_completion_in_record_lit); |
49 | return; | 49 | return; |
50 | } | 50 | } |
51 | let mut add_keyword = |kw, snippet| add_keyword(ctx, acc, kw, snippet); | ||
51 | 52 | ||
52 | let expects_assoc_item = ctx.expects_assoc_item(); | 53 | let expects_assoc_item = ctx.expects_assoc_item(); |
53 | let has_block_expr_parent = ctx.has_block_expr_parent(); | 54 | let has_block_expr_parent = ctx.has_block_expr_parent(); |
54 | let expects_item = ctx.expects_item(); | 55 | let expects_item = ctx.expects_item(); |
56 | |||
55 | if ctx.has_impl_or_trait_prev_sibling() { | 57 | if ctx.has_impl_or_trait_prev_sibling() { |
56 | add_keyword(ctx, acc, "where", "where "); | 58 | // FIXME this also incorrectly shows up after a complete trait/impl |
59 | add_keyword("where", "where "); | ||
57 | return; | 60 | return; |
58 | } | 61 | } |
59 | if ctx.previous_token_is(T![unsafe]) { | 62 | if ctx.previous_token_is(T![unsafe]) { |
60 | if expects_item || has_block_expr_parent { | 63 | if expects_item || expects_assoc_item || has_block_expr_parent { |
61 | add_keyword(ctx, acc, "fn", "fn $1($2) {\n $0\n}") | 64 | add_keyword("fn", "fn $1($2) {\n $0\n}") |
62 | } | 65 | } |
63 | 66 | ||
64 | if expects_item || has_block_expr_parent { | 67 | if expects_item || has_block_expr_parent { |
65 | add_keyword(ctx, acc, "trait", "trait $1 {\n $0\n}"); | 68 | add_keyword("trait", "trait $1 {\n $0\n}"); |
66 | add_keyword(ctx, acc, "impl", "impl $1 {\n $0\n}"); | 69 | add_keyword("impl", "impl $1 {\n $0\n}"); |
67 | } | 70 | } |
68 | 71 | ||
69 | return; | 72 | return; |
70 | } | 73 | } |
74 | |||
75 | if expects_item || ctx.expects_non_trait_assoc_item() || ctx.expect_record_field() { | ||
76 | add_keyword("pub(crate)", "pub(crate) "); | ||
77 | add_keyword("pub", "pub "); | ||
78 | } | ||
79 | |||
80 | if expects_item || expects_assoc_item || has_block_expr_parent || ctx.is_match_arm { | ||
81 | add_keyword("unsafe", "unsafe "); | ||
82 | } | ||
83 | |||
71 | if expects_item || expects_assoc_item || has_block_expr_parent { | 84 | if expects_item || expects_assoc_item || has_block_expr_parent { |
72 | add_keyword(ctx, acc, "fn", "fn $1($2) {\n $0\n}"); | 85 | add_keyword("fn", "fn $1($2) {\n $0\n}"); |
86 | add_keyword("const", "const $0"); | ||
87 | add_keyword("type", "type $0"); | ||
73 | } | 88 | } |
89 | |||
74 | if expects_item || has_block_expr_parent { | 90 | if expects_item || has_block_expr_parent { |
75 | add_keyword(ctx, acc, "use", "use "); | 91 | add_keyword("use", "use $0"); |
76 | add_keyword(ctx, acc, "impl", "impl $1 {\n $0\n}"); | 92 | add_keyword("impl", "impl $1 {\n $0\n}"); |
77 | add_keyword(ctx, acc, "trait", "trait $1 {\n $0\n}"); | 93 | add_keyword("trait", "trait $1 {\n $0\n}"); |
94 | add_keyword("static", "static $0"); | ||
95 | add_keyword("extern", "extern $0"); | ||
96 | add_keyword("mod", "mod $0"); | ||
78 | } | 97 | } |
79 | 98 | ||
80 | if expects_item { | 99 | if expects_item { |
81 | add_keyword(ctx, acc, "enum", "enum $1 {\n $0\n}"); | 100 | add_keyword("enum", "enum $1 {\n $0\n}"); |
82 | add_keyword(ctx, acc, "struct", "struct $0"); | 101 | add_keyword("struct", "struct $0"); |
83 | add_keyword(ctx, acc, "union", "union $1 {\n $0\n}"); | 102 | add_keyword("union", "union $1 {\n $0\n}"); |
84 | } | 103 | } |
85 | 104 | ||
86 | if ctx.is_expr { | 105 | if ctx.expects_expression() { |
87 | add_keyword(ctx, acc, "match", "match $1 {\n $0\n}"); | 106 | add_keyword("match", "match $1 {\n $0\n}"); |
88 | add_keyword(ctx, acc, "while", "while $1 {\n $0\n}"); | 107 | add_keyword("while", "while $1 {\n $0\n}"); |
89 | add_keyword(ctx, acc, "while let", "while let $1 = $2 {\n $0\n}"); | 108 | add_keyword("while let", "while let $1 = $2 {\n $0\n}"); |
90 | add_keyword(ctx, acc, "loop", "loop {\n $0\n}"); | 109 | add_keyword("loop", "loop {\n $0\n}"); |
91 | add_keyword(ctx, acc, "if", "if $1 {\n $0\n}"); | 110 | add_keyword("if", "if $1 {\n $0\n}"); |
92 | add_keyword(ctx, acc, "if let", "if let $1 = $2 {\n $0\n}"); | 111 | add_keyword("if let", "if let $1 = $2 {\n $0\n}"); |
93 | add_keyword(ctx, acc, "for", "for $1 in $2 {\n $0\n}"); | 112 | add_keyword("for", "for $1 in $2 {\n $0\n}"); |
94 | } | 113 | } |
95 | 114 | ||
96 | if ctx.previous_token_is(T![if]) || ctx.previous_token_is(T![while]) || has_block_expr_parent { | 115 | if ctx.previous_token_is(T![if]) || ctx.previous_token_is(T![while]) || has_block_expr_parent { |
97 | add_keyword(ctx, acc, "let", "let "); | 116 | add_keyword("let", "let "); |
98 | } | 117 | } |
99 | 118 | ||
100 | if ctx.after_if { | 119 | if ctx.after_if() { |
101 | add_keyword(ctx, acc, "else", "else {\n $0\n}"); | 120 | add_keyword("else", "else {\n $0\n}"); |
102 | add_keyword(ctx, acc, "else if", "else if $1 {\n $0\n}"); | 121 | add_keyword("else if", "else if $1 {\n $0\n}"); |
103 | } | ||
104 | if expects_item || has_block_expr_parent { | ||
105 | add_keyword(ctx, acc, "mod", "mod $0"); | ||
106 | } | 122 | } |
123 | |||
107 | if ctx.expects_ident_pat_or_ref_expr() { | 124 | if ctx.expects_ident_pat_or_ref_expr() { |
108 | add_keyword(ctx, acc, "mut", "mut "); | 125 | add_keyword("mut", "mut "); |
109 | } | ||
110 | if expects_item || expects_assoc_item || has_block_expr_parent { | ||
111 | add_keyword(ctx, acc, "const", "const "); | ||
112 | add_keyword(ctx, acc, "type", "type "); | ||
113 | } | ||
114 | if expects_item || has_block_expr_parent { | ||
115 | add_keyword(ctx, acc, "static", "static "); | ||
116 | }; | ||
117 | if expects_item || has_block_expr_parent { | ||
118 | add_keyword(ctx, acc, "extern", "extern "); | ||
119 | } | ||
120 | if expects_item || expects_assoc_item || has_block_expr_parent || ctx.is_match_arm { | ||
121 | add_keyword(ctx, acc, "unsafe", "unsafe "); | ||
122 | } | 126 | } |
127 | |||
123 | if ctx.in_loop_body { | 128 | if ctx.in_loop_body { |
124 | if ctx.can_be_stmt { | 129 | if ctx.can_be_stmt { |
125 | add_keyword(ctx, acc, "continue", "continue;"); | 130 | add_keyword("continue", "continue;"); |
126 | add_keyword(ctx, acc, "break", "break;"); | 131 | add_keyword("break", "break;"); |
127 | } else { | 132 | } else { |
128 | add_keyword(ctx, acc, "continue", "continue"); | 133 | add_keyword("continue", "continue"); |
129 | add_keyword(ctx, acc, "break", "break"); | 134 | add_keyword("break", "break"); |
130 | } | 135 | } |
131 | } | 136 | } |
132 | if expects_item || ctx.expects_non_trait_assoc_item() || ctx.expect_record_field() { | ||
133 | add_keyword(ctx, acc, "pub(crate)", "pub(crate) "); | ||
134 | add_keyword(ctx, acc, "pub", "pub "); | ||
135 | } | ||
136 | 137 | ||
137 | if !ctx.is_trivial_path { | 138 | if !ctx.is_trivial_path { |
138 | return; | 139 | return; |
@@ -143,8 +144,6 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
143 | }; | 144 | }; |
144 | 145 | ||
145 | add_keyword( | 146 | add_keyword( |
146 | ctx, | ||
147 | acc, | ||
148 | "return", | 147 | "return", |
149 | match (ctx.can_be_stmt, fn_def.ret_type().is_some()) { | 148 | match (ctx.can_be_stmt, fn_def.ret_type().is_some()) { |
150 | (true, true) => "return $0;", | 149 | (true, true) => "return $0;", |
@@ -161,15 +160,12 @@ fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet | |||
161 | 160 | ||
162 | match ctx.config.snippet_cap { | 161 | match ctx.config.snippet_cap { |
163 | Some(cap) => { | 162 | Some(cap) => { |
164 | let tmp; | 163 | if snippet.ends_with('}') && ctx.incomplete_let { |
165 | let snippet = if snippet.ends_with('}') && ctx.incomplete_let { | ||
166 | cov_mark::hit!(let_semi); | 164 | cov_mark::hit!(let_semi); |
167 | tmp = format!("{};", snippet); | 165 | item.insert_snippet(cap, format!("{};", snippet)); |
168 | &tmp | ||
169 | } else { | 166 | } else { |
170 | snippet | 167 | item.insert_snippet(cap, snippet); |
171 | }; | 168 | } |
172 | item.insert_snippet(cap, snippet); | ||
173 | } | 169 | } |
174 | None => { | 170 | None => { |
175 | item.insert_text(if snippet.contains('$') { kw } else { snippet }); | 171 | item.insert_text(if snippet.contains('$') { kw } else { snippet }); |
@@ -232,21 +228,21 @@ mod tests { | |||
232 | check( | 228 | check( |
233 | r"m$0", | 229 | r"m$0", |
234 | expect![[r#" | 230 | expect![[r#" |
231 | kw pub(crate) | ||
232 | kw pub | ||
233 | kw unsafe | ||
235 | kw fn | 234 | kw fn |
235 | kw const | ||
236 | kw type | ||
236 | kw use | 237 | kw use |
237 | kw impl | 238 | kw impl |
238 | kw trait | 239 | kw trait |
240 | kw static | ||
241 | kw extern | ||
242 | kw mod | ||
239 | kw enum | 243 | kw enum |
240 | kw struct | 244 | kw struct |
241 | kw union | 245 | kw union |
242 | kw mod | ||
243 | kw const | ||
244 | kw type | ||
245 | kw static | ||
246 | kw extern | ||
247 | kw unsafe | ||
248 | kw pub(crate) | ||
249 | kw pub | ||
250 | "#]], | 246 | "#]], |
251 | ); | 247 | ); |
252 | } | 248 | } |
@@ -256,10 +252,16 @@ mod tests { | |||
256 | check( | 252 | check( |
257 | r"fn quux() { $0 }", | 253 | r"fn quux() { $0 }", |
258 | expect![[r#" | 254 | expect![[r#" |
255 | kw unsafe | ||
259 | kw fn | 256 | kw fn |
257 | kw const | ||
258 | kw type | ||
260 | kw use | 259 | kw use |
261 | kw impl | 260 | kw impl |
262 | kw trait | 261 | kw trait |
262 | kw static | ||
263 | kw extern | ||
264 | kw mod | ||
263 | kw match | 265 | kw match |
264 | kw while | 266 | kw while |
265 | kw while let | 267 | kw while let |
@@ -268,12 +270,6 @@ mod tests { | |||
268 | kw if let | 270 | kw if let |
269 | kw for | 271 | kw for |
270 | kw let | 272 | kw let |
271 | kw mod | ||
272 | kw const | ||
273 | kw type | ||
274 | kw static | ||
275 | kw extern | ||
276 | kw unsafe | ||
277 | kw return | 273 | kw return |
278 | "#]], | 274 | "#]], |
279 | ); | 275 | ); |
@@ -284,10 +280,16 @@ mod tests { | |||
284 | check( | 280 | check( |
285 | r"fn quux() { if true { $0 } }", | 281 | r"fn quux() { if true { $0 } }", |
286 | expect![[r#" | 282 | expect![[r#" |
283 | kw unsafe | ||
287 | kw fn | 284 | kw fn |
285 | kw const | ||
286 | kw type | ||
288 | kw use | 287 | kw use |
289 | kw impl | 288 | kw impl |
290 | kw trait | 289 | kw trait |
290 | kw static | ||
291 | kw extern | ||
292 | kw mod | ||
291 | kw match | 293 | kw match |
292 | kw while | 294 | kw while |
293 | kw while let | 295 | kw while let |
@@ -296,12 +298,6 @@ mod tests { | |||
296 | kw if let | 298 | kw if let |
297 | kw for | 299 | kw for |
298 | kw let | 300 | kw let |
299 | kw mod | ||
300 | kw const | ||
301 | kw type | ||
302 | kw static | ||
303 | kw extern | ||
304 | kw unsafe | ||
305 | kw return | 301 | kw return |
306 | "#]], | 302 | "#]], |
307 | ); | 303 | ); |
@@ -312,10 +308,16 @@ mod tests { | |||
312 | check( | 308 | check( |
313 | r#"fn quux() { if true { () } $0 }"#, | 309 | r#"fn quux() { if true { () } $0 }"#, |
314 | expect![[r#" | 310 | expect![[r#" |
311 | kw unsafe | ||
315 | kw fn | 312 | kw fn |
313 | kw const | ||
314 | kw type | ||
316 | kw use | 315 | kw use |
317 | kw impl | 316 | kw impl |
318 | kw trait | 317 | kw trait |
318 | kw static | ||
319 | kw extern | ||
320 | kw mod | ||
319 | kw match | 321 | kw match |
320 | kw while | 322 | kw while |
321 | kw while let | 323 | kw while let |
@@ -326,12 +328,6 @@ mod tests { | |||
326 | kw let | 328 | kw let |
327 | kw else | 329 | kw else |
328 | kw else if | 330 | kw else if |
329 | kw mod | ||
330 | kw const | ||
331 | kw type | ||
332 | kw static | ||
333 | kw extern | ||
334 | kw unsafe | ||
335 | kw return | 331 | kw return |
336 | "#]], | 332 | "#]], |
337 | ); | 333 | ); |
@@ -353,6 +349,7 @@ fn quux() -> i32 { | |||
353 | } | 349 | } |
354 | "#, | 350 | "#, |
355 | expect![[r#" | 351 | expect![[r#" |
352 | kw unsafe | ||
356 | kw match | 353 | kw match |
357 | kw while | 354 | kw while |
358 | kw while let | 355 | kw while let |
@@ -360,7 +357,6 @@ fn quux() -> i32 { | |||
360 | kw if | 357 | kw if |
361 | kw if let | 358 | kw if let |
362 | kw for | 359 | kw for |
363 | kw unsafe | ||
364 | kw return | 360 | kw return |
365 | "#]], | 361 | "#]], |
366 | ); | 362 | ); |
@@ -371,10 +367,10 @@ fn quux() -> i32 { | |||
371 | check( | 367 | check( |
372 | r"trait My { $0 }", | 368 | r"trait My { $0 }", |
373 | expect![[r#" | 369 | expect![[r#" |
370 | kw unsafe | ||
374 | kw fn | 371 | kw fn |
375 | kw const | 372 | kw const |
376 | kw type | 373 | kw type |
377 | kw unsafe | ||
378 | "#]], | 374 | "#]], |
379 | ); | 375 | ); |
380 | } | 376 | } |
@@ -384,12 +380,12 @@ fn quux() -> i32 { | |||
384 | check( | 380 | check( |
385 | r"impl My { $0 }", | 381 | r"impl My { $0 }", |
386 | expect![[r#" | 382 | expect![[r#" |
383 | kw pub(crate) | ||
384 | kw pub | ||
385 | kw unsafe | ||
387 | kw fn | 386 | kw fn |
388 | kw const | 387 | kw const |
389 | kw type | 388 | kw type |
390 | kw unsafe | ||
391 | kw pub(crate) | ||
392 | kw pub | ||
393 | "#]], | 389 | "#]], |
394 | ); | 390 | ); |
395 | } | 391 | } |
@@ -399,12 +395,12 @@ fn quux() -> i32 { | |||
399 | check( | 395 | check( |
400 | r"impl My { #[foo] $0 }", | 396 | r"impl My { #[foo] $0 }", |
401 | expect![[r#" | 397 | expect![[r#" |
398 | kw pub(crate) | ||
399 | kw pub | ||
400 | kw unsafe | ||
402 | kw fn | 401 | kw fn |
403 | kw const | 402 | kw const |
404 | kw type | 403 | kw type |
405 | kw unsafe | ||
406 | kw pub(crate) | ||
407 | kw pub | ||
408 | "#]], | 404 | "#]], |
409 | ); | 405 | ); |
410 | } | 406 | } |
@@ -414,10 +410,16 @@ fn quux() -> i32 { | |||
414 | check( | 410 | check( |
415 | r"fn my() { loop { $0 } }", | 411 | r"fn my() { loop { $0 } }", |
416 | expect![[r#" | 412 | expect![[r#" |
413 | kw unsafe | ||
417 | kw fn | 414 | kw fn |
415 | kw const | ||
416 | kw type | ||
418 | kw use | 417 | kw use |
419 | kw impl | 418 | kw impl |
420 | kw trait | 419 | kw trait |
420 | kw static | ||
421 | kw extern | ||
422 | kw mod | ||
421 | kw match | 423 | kw match |
422 | kw while | 424 | kw while |
423 | kw while let | 425 | kw while let |
@@ -426,12 +428,6 @@ fn quux() -> i32 { | |||
426 | kw if let | 428 | kw if let |
427 | kw for | 429 | kw for |
428 | kw let | 430 | kw let |
429 | kw mod | ||
430 | kw const | ||
431 | kw type | ||
432 | kw static | ||
433 | kw extern | ||
434 | kw unsafe | ||
435 | kw continue | 431 | kw continue |
436 | kw break | 432 | kw break |
437 | kw return | 433 | kw return |