aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/completions/keyword.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/completions/keyword.rs')
-rw-r--r--crates/ide_completion/src/completions/keyword.rs85
1 files changed, 52 insertions, 33 deletions
diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs
index eb81f9765..b635e0ca3 100644
--- a/crates/ide_completion/src/completions/keyword.rs
+++ b/crates/ide_completion/src/completions/keyword.rs
@@ -1,7 +1,8 @@
1//! Completes keywords. 1//! Completes keywords.
2 2
3use std::iter;
4
3use syntax::SyntaxKind; 5use syntax::SyntaxKind;
4use test_utils::mark;
5 6
6use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions}; 7use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions};
7 8
@@ -11,29 +12,30 @@ pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC
11 12
12 if ctx.use_item_syntax.is_some() { 13 if ctx.use_item_syntax.is_some() {
13 if ctx.path_qual.is_none() { 14 if ctx.path_qual.is_none() {
14 CompletionItem::new(CompletionKind::Keyword, source_range, "crate::") 15 let mut item = CompletionItem::new(CompletionKind::Keyword, source_range, "crate::");
15 .kind(CompletionItemKind::Keyword) 16 item.kind(CompletionItemKind::Keyword).insert_text("crate::");
16 .insert_text("crate::") 17 item.add_to(acc);
17 .add_to(acc); 18 }
19 let mut item = CompletionItem::new(CompletionKind::Keyword, source_range, "self");
20 item.kind(CompletionItemKind::Keyword);
21 item.add_to(acc);
22 if iter::successors(ctx.path_qual.clone(), |p| p.qualifier())
23 .all(|p| p.segment().and_then(|s| s.super_token()).is_some())
24 {
25 let mut item = CompletionItem::new(CompletionKind::Keyword, source_range, "super::");
26 item.kind(CompletionItemKind::Keyword).insert_text("super::");
27 item.add_to(acc);
18 } 28 }
19 CompletionItem::new(CompletionKind::Keyword, source_range, "self")
20 .kind(CompletionItemKind::Keyword)
21 .add_to(acc);
22 CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
23 .kind(CompletionItemKind::Keyword)
24 .insert_text("super::")
25 .add_to(acc);
26 } 29 }
27 30
28 // Suggest .await syntax for types that implement Future trait 31 // Suggest .await syntax for types that implement Future trait
29 if let Some(receiver) = &ctx.dot_receiver { 32 if let Some(receiver) = &ctx.dot_receiver {
30 if let Some(ty) = ctx.sema.type_of_expr(receiver) { 33 if let Some(ty) = ctx.sema.type_of_expr(receiver) {
31 if ty.impls_future(ctx.db) { 34 if ty.impls_future(ctx.db) {
32 CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await") 35 let mut item =
33 .kind(CompletionItemKind::Keyword) 36 CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await");
34 .detail("expr.await") 37 item.kind(CompletionItemKind::Keyword).detail("expr.await").insert_text("await");
35 .insert_text("await") 38 item.add_to(acc);
36 .add_to(acc);
37 } 39 }
38 }; 40 };
39 } 41 }
@@ -41,11 +43,11 @@ pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC
41 43
42pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { 44pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
43 if ctx.token.kind() == SyntaxKind::COMMENT { 45 if ctx.token.kind() == SyntaxKind::COMMENT {
44 mark::hit!(no_keyword_completion_in_comments); 46 cov_mark::hit!(no_keyword_completion_in_comments);
45 return; 47 return;
46 } 48 }
47 if ctx.record_lit_syntax.is_some() { 49 if ctx.record_lit_syntax.is_some() {
48 mark::hit!(no_keyword_completion_in_record_lit); 50 cov_mark::hit!(no_keyword_completion_in_record_lit);
49 return; 51 return;
50 } 52 }
51 53
@@ -85,6 +87,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
85 if ctx.is_expr { 87 if ctx.is_expr {
86 add_keyword(ctx, acc, "match", "match $0 {}"); 88 add_keyword(ctx, acc, "match", "match $0 {}");
87 add_keyword(ctx, acc, "while", "while $0 {}"); 89 add_keyword(ctx, acc, "while", "while $0 {}");
90 add_keyword(ctx, acc, "while let", "while let $1 = $0 {}");
88 add_keyword(ctx, acc, "loop", "loop {$0}"); 91 add_keyword(ctx, acc, "loop", "loop {$0}");
89 add_keyword(ctx, acc, "if", "if $0 {}"); 92 add_keyword(ctx, acc, "if", "if $0 {}");
90 add_keyword(ctx, acc, "if let", "if let $1 = $0 {}"); 93 add_keyword(ctx, acc, "if let", "if let $1 = $0 {}");
@@ -159,29 +162,31 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
159} 162}
160 163
161fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet: &str) { 164fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet: &str) {
162 let builder = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), kw) 165 let mut item = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), kw);
163 .kind(CompletionItemKind::Keyword); 166 item.kind(CompletionItemKind::Keyword);
164 let builder = match ctx.config.snippet_cap { 167
168 match ctx.config.snippet_cap {
165 Some(cap) => { 169 Some(cap) => {
166 let tmp; 170 let tmp;
167 let snippet = if snippet.ends_with('}') && ctx.incomplete_let { 171 let snippet = if snippet.ends_with('}') && ctx.incomplete_let {
168 mark::hit!(let_semi); 172 cov_mark::hit!(let_semi);
169 tmp = format!("{};", snippet); 173 tmp = format!("{};", snippet);
170 &tmp 174 &tmp
171 } else { 175 } else {
172 snippet 176 snippet
173 }; 177 };
174 builder.insert_snippet(cap, snippet) 178 item.insert_snippet(cap, snippet);
179 }
180 None => {
181 item.insert_text(if snippet.contains('$') { kw } else { snippet });
175 } 182 }
176 None => builder.insert_text(if snippet.contains('$') { kw } else { snippet }),
177 }; 183 };
178 acc.add(builder.build()); 184 item.add_to(acc);
179} 185}
180 186
181#[cfg(test)] 187#[cfg(test)]
182mod tests { 188mod tests {
183 use expect_test::{expect, Expect}; 189 use expect_test::{expect, Expect};
184 use test_utils::mark;
185 190
186 use crate::{ 191 use crate::{
187 test_utils::{check_edit, completion_list}, 192 test_utils::{check_edit, completion_list},
@@ -204,9 +209,17 @@ mod tests {
204 "#]], 209 "#]],
205 ); 210 );
206 211
212 // FIXME: `self` shouldn't be shown here and the check below
207 check( 213 check(
208 r"use a::$0", 214 r"use a::$0",
209 expect![[r#" 215 expect![[r#"
216 kw self
217 "#]],
218 );
219
220 check(
221 r"use super::$0",
222 expect![[r#"
210 kw self 223 kw self
211 kw super:: 224 kw super::
212 "#]], 225 "#]],
@@ -215,9 +228,8 @@ mod tests {
215 check( 228 check(
216 r"use a::{b, $0}", 229 r"use a::{b, $0}",
217 expect![[r#" 230 expect![[r#"
218 kw self 231 kw self
219 kw super:: 232 "#]],
220 "#]],
221 ); 233 );
222 } 234 }
223 235
@@ -256,6 +268,7 @@ mod tests {
256 kw trait 268 kw trait
257 kw match 269 kw match
258 kw while 270 kw while
271 kw while let
259 kw loop 272 kw loop
260 kw if 273 kw if
261 kw if let 274 kw if let
@@ -283,6 +296,7 @@ mod tests {
283 kw trait 296 kw trait
284 kw match 297 kw match
285 kw while 298 kw while
299 kw while let
286 kw loop 300 kw loop
287 kw if 301 kw if
288 kw if let 302 kw if let
@@ -310,6 +324,7 @@ mod tests {
310 kw trait 324 kw trait
311 kw match 325 kw match
312 kw while 326 kw while
327 kw while let
313 kw loop 328 kw loop
314 kw if 329 kw if
315 kw if let 330 kw if let
@@ -344,6 +359,7 @@ fn quux() -> i32 {
344 expect![[r#" 359 expect![[r#"
345 kw match 360 kw match
346 kw while 361 kw while
362 kw while let
347 kw loop 363 kw loop
348 kw if 364 kw if
349 kw if let 365 kw if let
@@ -393,6 +409,7 @@ fn quux() -> i32 {
393 kw trait 409 kw trait
394 kw match 410 kw match
395 kw while 411 kw while
412 kw while let
396 kw loop 413 kw loop
397 kw if 414 kw if
398 kw if let 415 kw if let
@@ -475,7 +492,7 @@ fn quux() -> i32 {
475 492
476 #[test] 493 #[test]
477 fn no_keyword_completion_in_comments() { 494 fn no_keyword_completion_in_comments() {
478 mark::check!(no_keyword_completion_in_comments); 495 cov_mark::check!(no_keyword_completion_in_comments);
479 check( 496 check(
480 r#" 497 r#"
481fn test() { 498fn test() {
@@ -552,6 +569,7 @@ pub mod future {
552 expect![[r#" 569 expect![[r#"
553 kw match 570 kw match
554 kw while 571 kw while
572 kw while let
555 kw loop 573 kw loop
556 kw if 574 kw if
557 kw if let 575 kw if let
@@ -579,7 +597,7 @@ struct Foo {
579 597
580 #[test] 598 #[test]
581 fn skip_struct_initializer() { 599 fn skip_struct_initializer() {
582 mark::check!(no_keyword_completion_in_record_lit); 600 cov_mark::check!(no_keyword_completion_in_record_lit);
583 check( 601 check(
584 r#" 602 r#"
585struct Foo { 603struct Foo {
@@ -611,6 +629,7 @@ fn foo() {
611 expect![[r#" 629 expect![[r#"
612 kw match 630 kw match
613 kw while 631 kw while
632 kw while let
614 kw loop 633 kw loop
615 kw if 634 kw if
616 kw if let 635 kw if let
@@ -622,7 +641,7 @@ fn foo() {
622 641
623 #[test] 642 #[test]
624 fn let_semi() { 643 fn let_semi() {
625 mark::check!(let_semi); 644 cov_mark::check!(let_semi);
626 check_edit( 645 check_edit(
627 "match", 646 "match",
628 r#" 647 r#"