diff options
Diffstat (limited to 'crates/completion/src/completions')
-rw-r--r-- | crates/completion/src/completions/attribute.rs | 73 | ||||
-rw-r--r-- | crates/completion/src/completions/dot.rs | 48 | ||||
-rw-r--r-- | crates/completion/src/completions/fn_param.rs | 8 | ||||
-rw-r--r-- | crates/completion/src/completions/keyword.rs | 56 | ||||
-rw-r--r-- | crates/completion/src/completions/macro_in_item_position.rs | 2 | ||||
-rw-r--r-- | crates/completion/src/completions/mod_.rs | 87 | ||||
-rw-r--r-- | crates/completion/src/completions/pattern.rs | 20 | ||||
-rw-r--r-- | crates/completion/src/completions/postfix.rs | 79 | ||||
-rw-r--r-- | crates/completion/src/completions/postfix/format_like.rs | 7 | ||||
-rw-r--r-- | crates/completion/src/completions/qualified_path.rs | 70 | ||||
-rw-r--r-- | crates/completion/src/completions/record.rs | 94 | ||||
-rw-r--r-- | crates/completion/src/completions/snippet.rs | 14 | ||||
-rw-r--r-- | crates/completion/src/completions/trait_impl.rs | 123 | ||||
-rw-r--r-- | crates/completion/src/completions/unqualified_path.rs | 109 |
14 files changed, 426 insertions, 364 deletions
diff --git a/crates/completion/src/completions/attribute.rs b/crates/completion/src/completions/attribute.rs index 19ce2482f..e5522980d 100644 --- a/crates/completion/src/completions/attribute.rs +++ b/crates/completion/src/completions/attribute.rs | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | use itertools::Itertools; | 6 | use itertools::Itertools; |
7 | use rustc_hash::FxHashSet; | 7 | use rustc_hash::FxHashSet; |
8 | use syntax::{ast, AstNode, SyntaxKind}; | 8 | use syntax::{ast, AstNode, T}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | context::CompletionContext, | 11 | context::CompletionContext, |
@@ -21,19 +21,16 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) | |||
21 | 21 | ||
22 | let attribute = ctx.attribute_under_caret.as_ref()?; | 22 | let attribute = ctx.attribute_under_caret.as_ref()?; |
23 | match (attribute.path(), attribute.token_tree()) { | 23 | match (attribute.path(), attribute.token_tree()) { |
24 | (Some(path), Some(token_tree)) if path.to_string() == "derive" => { | 24 | (Some(path), Some(token_tree)) => { |
25 | complete_derive(acc, ctx, token_tree) | 25 | let path = path.syntax().text(); |
26 | } | 26 | if path == "derive" { |
27 | (Some(path), Some(token_tree)) if path.to_string() == "feature" => { | 27 | complete_derive(acc, ctx, token_tree) |
28 | complete_lint(acc, ctx, token_tree, FEATURES); | 28 | } else if path == "feature" { |
29 | } | 29 | complete_lint(acc, ctx, token_tree, FEATURES) |
30 | (Some(path), Some(token_tree)) | 30 | } else if path == "allow" || path == "warn" || path == "deny" || path == "forbid" { |
31 | if ["allow", "warn", "deny", "forbid"] | 31 | complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINT_COMPLETIONS); |
32 | .iter() | 32 | complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); |
33 | .any(|lint_level| lint_level == &path.to_string()) => | 33 | } |
34 | { | ||
35 | complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINT_COMPLETIONS); | ||
36 | complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); | ||
37 | } | 34 | } |
38 | (_, Some(_token_tree)) => {} | 35 | (_, Some(_token_tree)) => {} |
39 | _ => complete_attribute_start(acc, ctx, attribute), | 36 | _ => complete_attribute_start(acc, ctx, attribute), |
@@ -54,11 +51,8 @@ fn complete_attribute_start(acc: &mut Completions, ctx: &CompletionContext, attr | |||
54 | item = item.lookup_by(lookup); | 51 | item = item.lookup_by(lookup); |
55 | } | 52 | } |
56 | 53 | ||
57 | match (attr_completion.snippet, ctx.config.snippet_cap) { | 54 | if let Some((snippet, cap)) = attr_completion.snippet.zip(ctx.config.snippet_cap) { |
58 | (Some(snippet), Some(cap)) => { | 55 | item = item.insert_snippet(cap, snippet); |
59 | item = item.insert_snippet(cap, snippet); | ||
60 | } | ||
61 | _ => {} | ||
62 | } | 56 | } |
63 | 57 | ||
64 | if attribute.kind() == ast::AttrKind::Inner || !attr_completion.prefer_inner { | 58 | if attribute.kind() == ast::AttrKind::Inner || !attr_completion.prefer_inner { |
@@ -98,7 +92,7 @@ const ATTRIBUTES: &[AttrCompletion] = &[ | |||
98 | attr(r#"crate_name = """#, Some("crate_name"), Some(r#"crate_name = "${0:crate_name}""#)) | 92 | attr(r#"crate_name = """#, Some("crate_name"), Some(r#"crate_name = "${0:crate_name}""#)) |
99 | .prefer_inner(), | 93 | .prefer_inner(), |
100 | attr("deny(…)", Some("deny"), Some("deny(${0:lint})")), | 94 | attr("deny(…)", Some("deny"), Some("deny(${0:lint})")), |
101 | attr(r#"deprecated = "…""#, Some("deprecated"), Some(r#"deprecated = "${0:reason}""#)), | 95 | attr(r#"deprecated"#, Some("deprecated"), Some(r#"deprecated"#)), |
102 | attr("derive(…)", Some("derive"), Some(r#"derive(${0:Debug})"#)), | 96 | attr("derive(…)", Some("derive"), Some(r#"derive(${0:Debug})"#)), |
103 | attr( | 97 | attr( |
104 | r#"export_name = "…""#, | 98 | r#"export_name = "…""#, |
@@ -121,7 +115,7 @@ const ATTRIBUTES: &[AttrCompletion] = &[ | |||
121 | ), | 115 | ), |
122 | attr("macro_export", None, None), | 116 | attr("macro_export", None, None), |
123 | attr("macro_use", None, None), | 117 | attr("macro_use", None, None), |
124 | attr(r#"must_use = "…""#, Some("must_use"), Some(r#"must_use = "${0:reason}""#)), | 118 | attr(r#"must_use"#, Some("must_use"), Some(r#"must_use"#)), |
125 | attr("no_link", None, None).prefer_inner(), | 119 | attr("no_link", None, None).prefer_inner(), |
126 | attr("no_implicit_prelude", None, None).prefer_inner(), | 120 | attr("no_implicit_prelude", None, None).prefer_inner(), |
127 | attr("no_main", None, None).prefer_inner(), | 121 | attr("no_main", None, None).prefer_inner(), |
@@ -136,11 +130,7 @@ const ATTRIBUTES: &[AttrCompletion] = &[ | |||
136 | attr("recursion_limit = …", Some("recursion_limit"), Some("recursion_limit = ${0:128}")) | 130 | attr("recursion_limit = …", Some("recursion_limit"), Some("recursion_limit = ${0:128}")) |
137 | .prefer_inner(), | 131 | .prefer_inner(), |
138 | attr("repr(…)", Some("repr"), Some("repr(${0:C})")), | 132 | attr("repr(…)", Some("repr"), Some("repr(${0:C})")), |
139 | attr( | 133 | attr("should_panic", Some("should_panic"), Some(r#"should_panic"#)), |
140 | "should_panic(…)", | ||
141 | Some("should_panic"), | ||
142 | Some(r#"should_panic(expected = "${0:reason}")"#), | ||
143 | ), | ||
144 | attr( | 134 | attr( |
145 | r#"target_feature = "…""#, | 135 | r#"target_feature = "…""#, |
146 | Some("target_feature"), | 136 | Some("target_feature"), |
@@ -215,8 +205,7 @@ fn complete_lint( | |||
215 | fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Result<FxHashSet<String>, ()> { | 205 | fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Result<FxHashSet<String>, ()> { |
216 | match (derive_input.left_delimiter_token(), derive_input.right_delimiter_token()) { | 206 | match (derive_input.left_delimiter_token(), derive_input.right_delimiter_token()) { |
217 | (Some(left_paren), Some(right_paren)) | 207 | (Some(left_paren), Some(right_paren)) |
218 | if left_paren.kind() == SyntaxKind::L_PAREN | 208 | if left_paren.kind() == T!['('] && right_paren.kind() == T![')'] => |
219 | && right_paren.kind() == SyntaxKind::R_PAREN => | ||
220 | { | 209 | { |
221 | let mut input_derives = FxHashSet::default(); | 210 | let mut input_derives = FxHashSet::default(); |
222 | let mut current_derive = String::new(); | 211 | let mut current_derive = String::new(); |
@@ -228,13 +217,13 @@ fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Result<FxHashSet<Strin | |||
228 | .skip(1) | 217 | .skip(1) |
229 | .take_while(|token| token != &right_paren) | 218 | .take_while(|token| token != &right_paren) |
230 | { | 219 | { |
231 | if SyntaxKind::COMMA == token.kind() { | 220 | if T![,] == token.kind() { |
232 | if !current_derive.is_empty() { | 221 | if !current_derive.is_empty() { |
233 | input_derives.insert(current_derive); | 222 | input_derives.insert(current_derive); |
234 | current_derive = String::new(); | 223 | current_derive = String::new(); |
235 | } | 224 | } |
236 | } else { | 225 | } else { |
237 | current_derive.push_str(token.to_string().trim()); | 226 | current_derive.push_str(token.text().trim()); |
238 | } | 227 | } |
239 | } | 228 | } |
240 | 229 | ||
@@ -417,7 +406,7 @@ mod tests { | |||
417 | fn empty_derive_completion() { | 406 | fn empty_derive_completion() { |
418 | check( | 407 | check( |
419 | r#" | 408 | r#" |
420 | #[derive(<|>)] | 409 | #[derive($0)] |
421 | struct Test {} | 410 | struct Test {} |
422 | "#, | 411 | "#, |
423 | expect![[r#" | 412 | expect![[r#" |
@@ -438,7 +427,7 @@ struct Test {} | |||
438 | fn no_completion_for_incorrect_derive() { | 427 | fn no_completion_for_incorrect_derive() { |
439 | check( | 428 | check( |
440 | r#" | 429 | r#" |
441 | #[derive{<|>)] | 430 | #[derive{$0)] |
442 | struct Test {} | 431 | struct Test {} |
443 | "#, | 432 | "#, |
444 | expect![[r#""#]], | 433 | expect![[r#""#]], |
@@ -449,7 +438,7 @@ struct Test {} | |||
449 | fn derive_with_input_completion() { | 438 | fn derive_with_input_completion() { |
450 | check( | 439 | check( |
451 | r#" | 440 | r#" |
452 | #[derive(serde::Serialize, PartialEq, <|>)] | 441 | #[derive(serde::Serialize, PartialEq, $0)] |
453 | struct Test {} | 442 | struct Test {} |
454 | "#, | 443 | "#, |
455 | expect![[r#" | 444 | expect![[r#" |
@@ -468,7 +457,7 @@ struct Test {} | |||
468 | #[test] | 457 | #[test] |
469 | fn test_attribute_completion() { | 458 | fn test_attribute_completion() { |
470 | check( | 459 | check( |
471 | r#"#[<|>]"#, | 460 | r#"#[$0]"#, |
472 | expect![[r#" | 461 | expect![[r#" |
473 | at allow(…) | 462 | at allow(…) |
474 | at automatically_derived | 463 | at automatically_derived |
@@ -476,7 +465,7 @@ struct Test {} | |||
476 | at cfg(…) | 465 | at cfg(…) |
477 | at cold | 466 | at cold |
478 | at deny(…) | 467 | at deny(…) |
479 | at deprecated = "…" | 468 | at deprecated |
480 | at derive(…) | 469 | at derive(…) |
481 | at export_name = "…" | 470 | at export_name = "…" |
482 | at doc = "…" | 471 | at doc = "…" |
@@ -488,7 +477,7 @@ struct Test {} | |||
488 | at link_section = "…" | 477 | at link_section = "…" |
489 | at macro_export | 478 | at macro_export |
490 | at macro_use | 479 | at macro_use |
491 | at must_use = "…" | 480 | at must_use |
492 | at no_mangle | 481 | at no_mangle |
493 | at non_exhaustive | 482 | at non_exhaustive |
494 | at path = "…" | 483 | at path = "…" |
@@ -496,7 +485,7 @@ struct Test {} | |||
496 | at proc_macro_attribute | 485 | at proc_macro_attribute |
497 | at proc_macro_derive(…) | 486 | at proc_macro_derive(…) |
498 | at repr(…) | 487 | at repr(…) |
499 | at should_panic(…) | 488 | at should_panic |
500 | at target_feature = "…" | 489 | at target_feature = "…" |
501 | at test | 490 | at test |
502 | at track_caller | 491 | at track_caller |
@@ -508,13 +497,13 @@ struct Test {} | |||
508 | 497 | ||
509 | #[test] | 498 | #[test] |
510 | fn test_attribute_completion_inside_nested_attr() { | 499 | fn test_attribute_completion_inside_nested_attr() { |
511 | check(r#"#[cfg(<|>)]"#, expect![[]]) | 500 | check(r#"#[cfg($0)]"#, expect![[]]) |
512 | } | 501 | } |
513 | 502 | ||
514 | #[test] | 503 | #[test] |
515 | fn test_inner_attribute_completion() { | 504 | fn test_inner_attribute_completion() { |
516 | check( | 505 | check( |
517 | r"#![<|>]", | 506 | r"#![$0]", |
518 | expect![[r#" | 507 | expect![[r#" |
519 | at allow(…) | 508 | at allow(…) |
520 | at automatically_derived | 509 | at automatically_derived |
@@ -523,7 +512,7 @@ struct Test {} | |||
523 | at cold | 512 | at cold |
524 | at crate_name = "" | 513 | at crate_name = "" |
525 | at deny(…) | 514 | at deny(…) |
526 | at deprecated = "…" | 515 | at deprecated |
527 | at derive(…) | 516 | at derive(…) |
528 | at export_name = "…" | 517 | at export_name = "…" |
529 | at doc = "…" | 518 | at doc = "…" |
@@ -537,7 +526,7 @@ struct Test {} | |||
537 | at link_section = "…" | 526 | at link_section = "…" |
538 | at macro_export | 527 | at macro_export |
539 | at macro_use | 528 | at macro_use |
540 | at must_use = "…" | 529 | at must_use |
541 | at no_link | 530 | at no_link |
542 | at no_implicit_prelude | 531 | at no_implicit_prelude |
543 | at no_main | 532 | at no_main |
@@ -551,7 +540,7 @@ struct Test {} | |||
551 | at proc_macro_derive(…) | 540 | at proc_macro_derive(…) |
552 | at recursion_limit = … | 541 | at recursion_limit = … |
553 | at repr(…) | 542 | at repr(…) |
554 | at should_panic(…) | 543 | at should_panic |
555 | at target_feature = "…" | 544 | at target_feature = "…" |
556 | at test | 545 | at test |
557 | at track_caller | 546 | at track_caller |
diff --git a/crates/completion/src/completions/dot.rs b/crates/completion/src/completions/dot.rs index 551ef1771..d04eef65a 100644 --- a/crates/completion/src/completions/dot.rs +++ b/crates/completion/src/completions/dot.rs | |||
@@ -79,7 +79,7 @@ struct S { foo: u32 } | |||
79 | impl S { | 79 | impl S { |
80 | fn bar(&self) {} | 80 | fn bar(&self) {} |
81 | } | 81 | } |
82 | fn foo(s: S) { s.<|> } | 82 | fn foo(s: S) { s.$0 } |
83 | "#, | 83 | "#, |
84 | expect![[r#" | 84 | expect![[r#" |
85 | fd foo u32 | 85 | fd foo u32 |
@@ -94,7 +94,7 @@ fn foo(s: S) { s.<|> } | |||
94 | r#" | 94 | r#" |
95 | struct S { the_field: (u32,) } | 95 | struct S { the_field: (u32,) } |
96 | impl S { | 96 | impl S { |
97 | fn foo(self) { self.<|> } | 97 | fn foo(self) { self.$0 } |
98 | } | 98 | } |
99 | "#, | 99 | "#, |
100 | expect![[r#" | 100 | expect![[r#" |
@@ -110,7 +110,7 @@ impl S { | |||
110 | r#" | 110 | r#" |
111 | struct A { the_field: (u32, i32) } | 111 | struct A { the_field: (u32, i32) } |
112 | impl A { | 112 | impl A { |
113 | fn foo(&self) { self.<|> } | 113 | fn foo(&self) { self.$0 } |
114 | } | 114 | } |
115 | "#, | 115 | "#, |
116 | expect![[r#" | 116 | expect![[r#" |
@@ -126,7 +126,7 @@ impl A { | |||
126 | check( | 126 | check( |
127 | r#" | 127 | r#" |
128 | struct A { the_field: u32 } | 128 | struct A { the_field: u32 } |
129 | fn foo(a: A) { a.<|>() } | 129 | fn foo(a: A) { a.$0() } |
130 | "#, | 130 | "#, |
131 | expect![[""]], | 131 | expect![[""]], |
132 | ); | 132 | ); |
@@ -144,7 +144,7 @@ mod inner { | |||
144 | pub(crate) super_field: u32, | 144 | pub(crate) super_field: u32, |
145 | } | 145 | } |
146 | } | 146 | } |
147 | fn foo(a: inner::A) { a.<|> } | 147 | fn foo(a: inner::A) { a.$0 } |
148 | "#, | 148 | "#, |
149 | expect![[r#" | 149 | expect![[r#" |
150 | fd pub_field u32 | 150 | fd pub_field u32 |
@@ -162,7 +162,7 @@ mod m { | |||
162 | pub(crate) fn the_method(&self) {} | 162 | pub(crate) fn the_method(&self) {} |
163 | } | 163 | } |
164 | } | 164 | } |
165 | fn foo(a: A) { a.<|> } | 165 | fn foo(a: A) { a.$0 } |
166 | "#, | 166 | "#, |
167 | expect![[r#" | 167 | expect![[r#" |
168 | me the_method() pub(crate) fn the_method(&self) | 168 | me the_method() pub(crate) fn the_method(&self) |
@@ -175,7 +175,7 @@ fn foo(a: A) { a.<|> } | |||
175 | check( | 175 | check( |
176 | r#" | 176 | r#" |
177 | union U { field: u8, other: u16 } | 177 | union U { field: u8, other: u16 } |
178 | fn foo(u: U) { u.<|> } | 178 | fn foo(u: U) { u.$0 } |
179 | "#, | 179 | "#, |
180 | expect![[r#" | 180 | expect![[r#" |
181 | fd field u8 | 181 | fd field u8 |
@@ -195,7 +195,7 @@ impl A<u32> { | |||
195 | impl A<i32> { | 195 | impl A<i32> { |
196 | fn the_other_method(&self) {} | 196 | fn the_other_method(&self) {} |
197 | } | 197 | } |
198 | fn foo(a: A<u32>) { a.<|> } | 198 | fn foo(a: A<u32>) { a.$0 } |
199 | "#, | 199 | "#, |
200 | expect![[r#" | 200 | expect![[r#" |
201 | me the_method() fn the_method(&self) | 201 | me the_method() fn the_method(&self) |
@@ -210,7 +210,7 @@ fn foo(a: A<u32>) { a.<|> } | |||
210 | struct A {} | 210 | struct A {} |
211 | trait Trait { fn the_method(&self); } | 211 | trait Trait { fn the_method(&self); } |
212 | impl Trait for A {} | 212 | impl Trait for A {} |
213 | fn foo(a: A) { a.<|> } | 213 | fn foo(a: A) { a.$0 } |
214 | "#, | 214 | "#, |
215 | expect![[r#" | 215 | expect![[r#" |
216 | me the_method() fn the_method(&self) | 216 | me the_method() fn the_method(&self) |
@@ -225,7 +225,7 @@ fn foo(a: A) { a.<|> } | |||
225 | struct A {} | 225 | struct A {} |
226 | trait Trait { fn the_method(&self); } | 226 | trait Trait { fn the_method(&self); } |
227 | impl<T> Trait for T {} | 227 | impl<T> Trait for T {} |
228 | fn foo(a: &A) { a.<|> } | 228 | fn foo(a: &A) { a.$0 } |
229 | ", | 229 | ", |
230 | expect![[r#" | 230 | expect![[r#" |
231 | me the_method() fn the_method(&self) | 231 | me the_method() fn the_method(&self) |
@@ -243,7 +243,7 @@ mod m { | |||
243 | } | 243 | } |
244 | use m::Trait; | 244 | use m::Trait; |
245 | impl Trait for A {} | 245 | impl Trait for A {} |
246 | fn foo(a: A) { a.<|> } | 246 | fn foo(a: A) { a.$0 } |
247 | ", | 247 | ", |
248 | expect![[r#" | 248 | expect![[r#" |
249 | me the_method() fn the_method(&self) | 249 | me the_method() fn the_method(&self) |
@@ -260,7 +260,7 @@ impl A { | |||
260 | fn the_method() {} | 260 | fn the_method() {} |
261 | } | 261 | } |
262 | fn foo(a: A) { | 262 | fn foo(a: A) { |
263 | a.<|> | 263 | a.$0 |
264 | } | 264 | } |
265 | "#, | 265 | "#, |
266 | expect![[""]], | 266 | expect![[""]], |
@@ -273,7 +273,7 @@ fn foo(a: A) { | |||
273 | r#" | 273 | r#" |
274 | fn foo() { | 274 | fn foo() { |
275 | let b = (0, 3.14); | 275 | let b = (0, 3.14); |
276 | b.<|> | 276 | b.$0 |
277 | } | 277 | } |
278 | "#, | 278 | "#, |
279 | expect![[r#" | 279 | expect![[r#" |
@@ -295,7 +295,7 @@ struct T(S); | |||
295 | impl T { | 295 | impl T { |
296 | fn foo(&self) { | 296 | fn foo(&self) { |
297 | // FIXME: This doesn't work without the trailing `a` as `0.` is a float | 297 | // FIXME: This doesn't work without the trailing `a` as `0.` is a float |
298 | self.0.a<|> | 298 | self.0.a$0 |
299 | } | 299 | } |
300 | } | 300 | } |
301 | "#, | 301 | "#, |
@@ -311,7 +311,7 @@ impl T { | |||
311 | r#" | 311 | r#" |
312 | struct A { the_field: u32 } | 312 | struct A { the_field: u32 } |
313 | const X: u32 = { | 313 | const X: u32 = { |
314 | A { the_field: 92 }.<|> | 314 | A { the_field: 92 }.$0 |
315 | }; | 315 | }; |
316 | "#, | 316 | "#, |
317 | expect![[r#" | 317 | expect![[r#" |
@@ -327,7 +327,7 @@ const X: u32 = { | |||
327 | macro_rules! m { ($e:expr) => { $e } } | 327 | macro_rules! m { ($e:expr) => { $e } } |
328 | struct A { the_field: u32 } | 328 | struct A { the_field: u32 } |
329 | fn foo(a: A) { | 329 | fn foo(a: A) { |
330 | m!(a.x<|>) | 330 | m!(a.x$0) |
331 | } | 331 | } |
332 | "#, | 332 | "#, |
333 | expect![[r#" | 333 | expect![[r#" |
@@ -344,7 +344,7 @@ fn foo(a: A) { | |||
344 | macro_rules! m { ($e:expr) => { $e } } | 344 | macro_rules! m { ($e:expr) => { $e } } |
345 | struct A { the_field: u32 } | 345 | struct A { the_field: u32 } |
346 | fn foo(a: A) { | 346 | fn foo(a: A) { |
347 | m!(a.<|>) | 347 | m!(a.$0) |
348 | } | 348 | } |
349 | "#, | 349 | "#, |
350 | expect![[r#" | 350 | expect![[r#" |
@@ -360,7 +360,7 @@ fn foo(a: A) { | |||
360 | macro_rules! m { ($e:expr) => { $e } } | 360 | macro_rules! m { ($e:expr) => { $e } } |
361 | struct A { the_field: u32 } | 361 | struct A { the_field: u32 } |
362 | fn foo(a: A) { | 362 | fn foo(a: A) { |
363 | m!(m!(m!(a.x<|>))) | 363 | m!(m!(m!(a.x$0))) |
364 | } | 364 | } |
365 | "#, | 365 | "#, |
366 | expect![[r#" | 366 | expect![[r#" |
@@ -373,20 +373,20 @@ fn foo(a: A) { | |||
373 | fn macro_expansion_resilient() { | 373 | fn macro_expansion_resilient() { |
374 | check( | 374 | check( |
375 | r#" | 375 | r#" |
376 | macro_rules! dbg { | 376 | macro_rules! d { |
377 | () => {}; | 377 | () => {}; |
378 | ($val:expr) => { | 378 | ($val:expr) => { |
379 | match $val { tmp => { tmp } } | 379 | match $val { tmp => { tmp } } |
380 | }; | 380 | }; |
381 | // Trailing comma with single argument is ignored | 381 | // Trailing comma with single argument is ignored |
382 | ($val:expr,) => { $crate::dbg!($val) }; | 382 | ($val:expr,) => { $crate::d!($val) }; |
383 | ($($val:expr),+ $(,)?) => { | 383 | ($($val:expr),+ $(,)?) => { |
384 | ($($crate::dbg!($val)),+,) | 384 | ($($crate::d!($val)),+,) |
385 | }; | 385 | }; |
386 | } | 386 | } |
387 | struct A { the_field: u32 } | 387 | struct A { the_field: u32 } |
388 | fn foo(a: A) { | 388 | fn foo(a: A) { |
389 | dbg!(a.<|>) | 389 | d!(a.$0) |
390 | } | 390 | } |
391 | "#, | 391 | "#, |
392 | expect![[r#" | 392 | expect![[r#" |
@@ -405,7 +405,7 @@ impl<T> HashSet<T> { | |||
405 | } | 405 | } |
406 | fn foo() { | 406 | fn foo() { |
407 | let s: HashSet<_>; | 407 | let s: HashSet<_>; |
408 | s.<|> | 408 | s.$0 |
409 | } | 409 | } |
410 | "#, | 410 | "#, |
411 | expect![[r#" | 411 | expect![[r#" |
@@ -421,7 +421,7 @@ fn foo() { | |||
421 | struct S; | 421 | struct S; |
422 | impl S { fn foo(&self) {} } | 422 | impl S { fn foo(&self) {} } |
423 | macro_rules! make_s { () => { S }; } | 423 | macro_rules! make_s { () => { S }; } |
424 | fn main() { make_s!().f<|>; } | 424 | fn main() { make_s!().f$0; } |
425 | "#, | 425 | "#, |
426 | expect![[r#" | 426 | expect![[r#" |
427 | me foo() fn foo(&self) | 427 | me foo() fn foo(&self) |
diff --git a/crates/completion/src/completions/fn_param.rs b/crates/completion/src/completions/fn_param.rs index e777a53c1..5505c3559 100644 --- a/crates/completion/src/completions/fn_param.rs +++ b/crates/completion/src/completions/fn_param.rs | |||
@@ -81,7 +81,7 @@ mod tests { | |||
81 | r#" | 81 | r#" |
82 | fn foo(file_id: FileId) {} | 82 | fn foo(file_id: FileId) {} |
83 | fn bar(file_id: FileId) {} | 83 | fn bar(file_id: FileId) {} |
84 | fn baz(file<|>) {} | 84 | fn baz(file$0) {} |
85 | "#, | 85 | "#, |
86 | expect![[r#" | 86 | expect![[r#" |
87 | bn file_id: FileId | 87 | bn file_id: FileId |
@@ -94,7 +94,7 @@ fn baz(file<|>) {} | |||
94 | check( | 94 | check( |
95 | r#" | 95 | r#" |
96 | fn foo(file_id: FileId) {} | 96 | fn foo(file_id: FileId) {} |
97 | fn baz(file<|>, x: i32) {} | 97 | fn baz(file$0, x: i32) {} |
98 | "#, | 98 | "#, |
99 | expect![[r#" | 99 | expect![[r#" |
100 | bn file_id: FileId | 100 | bn file_id: FileId |
@@ -110,7 +110,7 @@ pub(crate) trait SourceRoot { | |||
110 | pub fn contains(&self, file_id: FileId) -> bool; | 110 | pub fn contains(&self, file_id: FileId) -> bool; |
111 | pub fn module_map(&self) -> &ModuleMap; | 111 | pub fn module_map(&self) -> &ModuleMap; |
112 | pub fn lines(&self, file_id: FileId) -> &LineIndex; | 112 | pub fn lines(&self, file_id: FileId) -> &LineIndex; |
113 | pub fn syntax(&self, file<|>) | 113 | pub fn syntax(&self, file$0) |
114 | } | 114 | } |
115 | "#, | 115 | "#, |
116 | expect![[r#" | 116 | expect![[r#" |
@@ -124,7 +124,7 @@ pub(crate) trait SourceRoot { | |||
124 | check( | 124 | check( |
125 | r#" | 125 | r#" |
126 | fn outer(text: String) { | 126 | fn outer(text: String) { |
127 | fn inner(<|>) | 127 | fn inner($0) |
128 | } | 128 | } |
129 | "#, | 129 | "#, |
130 | expect![[r#" | 130 | expect![[r#" |
diff --git a/crates/completion/src/completions/keyword.rs b/crates/completion/src/completions/keyword.rs index 1859dec70..425a688ff 100644 --- a/crates/completion/src/completions/keyword.rs +++ b/crates/completion/src/completions/keyword.rs | |||
@@ -193,7 +193,7 @@ mod tests { | |||
193 | #[test] | 193 | #[test] |
194 | fn test_keywords_in_use_stmt() { | 194 | fn test_keywords_in_use_stmt() { |
195 | check( | 195 | check( |
196 | r"use <|>", | 196 | r"use $0", |
197 | expect![[r#" | 197 | expect![[r#" |
198 | kw crate:: | 198 | kw crate:: |
199 | kw self | 199 | kw self |
@@ -202,7 +202,7 @@ mod tests { | |||
202 | ); | 202 | ); |
203 | 203 | ||
204 | check( | 204 | check( |
205 | r"use a::<|>", | 205 | r"use a::$0", |
206 | expect![[r#" | 206 | expect![[r#" |
207 | kw self | 207 | kw self |
208 | kw super:: | 208 | kw super:: |
@@ -210,7 +210,7 @@ mod tests { | |||
210 | ); | 210 | ); |
211 | 211 | ||
212 | check( | 212 | check( |
213 | r"use a::{b, <|>}", | 213 | r"use a::{b, $0}", |
214 | expect![[r#" | 214 | expect![[r#" |
215 | kw self | 215 | kw self |
216 | kw super:: | 216 | kw super:: |
@@ -221,7 +221,7 @@ mod tests { | |||
221 | #[test] | 221 | #[test] |
222 | fn test_keywords_at_source_file_level() { | 222 | fn test_keywords_at_source_file_level() { |
223 | check( | 223 | check( |
224 | r"m<|>", | 224 | r"m$0", |
225 | expect![[r#" | 225 | expect![[r#" |
226 | kw fn | 226 | kw fn |
227 | kw use | 227 | kw use |
@@ -245,7 +245,7 @@ mod tests { | |||
245 | #[test] | 245 | #[test] |
246 | fn test_keywords_in_function() { | 246 | fn test_keywords_in_function() { |
247 | check( | 247 | check( |
248 | r"fn quux() { <|> }", | 248 | r"fn quux() { $0 }", |
249 | expect![[r#" | 249 | expect![[r#" |
250 | kw fn | 250 | kw fn |
251 | kw use | 251 | kw use |
@@ -271,7 +271,7 @@ mod tests { | |||
271 | #[test] | 271 | #[test] |
272 | fn test_keywords_inside_block() { | 272 | fn test_keywords_inside_block() { |
273 | check( | 273 | check( |
274 | r"fn quux() { if true { <|> } }", | 274 | r"fn quux() { if true { $0 } }", |
275 | expect![[r#" | 275 | expect![[r#" |
276 | kw fn | 276 | kw fn |
277 | kw use | 277 | kw use |
@@ -297,7 +297,7 @@ mod tests { | |||
297 | #[test] | 297 | #[test] |
298 | fn test_keywords_after_if() { | 298 | fn test_keywords_after_if() { |
299 | check( | 299 | check( |
300 | r#"fn quux() { if true { () } <|> }"#, | 300 | r#"fn quux() { if true { () } $0 }"#, |
301 | expect![[r#" | 301 | expect![[r#" |
302 | kw fn | 302 | kw fn |
303 | kw use | 303 | kw use |
@@ -322,7 +322,7 @@ mod tests { | |||
322 | ); | 322 | ); |
323 | check_edit( | 323 | check_edit( |
324 | "else", | 324 | "else", |
325 | r#"fn quux() { if true { () } <|> }"#, | 325 | r#"fn quux() { if true { () } $0 }"#, |
326 | r#"fn quux() { if true { () } else {$0} }"#, | 326 | r#"fn quux() { if true { () } else {$0} }"#, |
327 | ); | 327 | ); |
328 | } | 328 | } |
@@ -332,7 +332,7 @@ mod tests { | |||
332 | check( | 332 | check( |
333 | r#" | 333 | r#" |
334 | fn quux() -> i32 { | 334 | fn quux() -> i32 { |
335 | match () { () => <|> } | 335 | match () { () => $0 } |
336 | } | 336 | } |
337 | "#, | 337 | "#, |
338 | expect![[r#" | 338 | expect![[r#" |
@@ -350,7 +350,7 @@ fn quux() -> i32 { | |||
350 | #[test] | 350 | #[test] |
351 | fn test_keywords_in_trait_def() { | 351 | fn test_keywords_in_trait_def() { |
352 | check( | 352 | check( |
353 | r"trait My { <|> }", | 353 | r"trait My { $0 }", |
354 | expect![[r#" | 354 | expect![[r#" |
355 | kw fn | 355 | kw fn |
356 | kw const | 356 | kw const |
@@ -363,7 +363,7 @@ fn quux() -> i32 { | |||
363 | #[test] | 363 | #[test] |
364 | fn test_keywords_in_impl_def() { | 364 | fn test_keywords_in_impl_def() { |
365 | check( | 365 | check( |
366 | r"impl My { <|> }", | 366 | r"impl My { $0 }", |
367 | expect![[r#" | 367 | expect![[r#" |
368 | kw fn | 368 | kw fn |
369 | kw const | 369 | kw const |
@@ -378,7 +378,7 @@ fn quux() -> i32 { | |||
378 | #[test] | 378 | #[test] |
379 | fn test_keywords_in_loop() { | 379 | fn test_keywords_in_loop() { |
380 | check( | 380 | check( |
381 | r"fn my() { loop { <|> } }", | 381 | r"fn my() { loop { $0 } }", |
382 | expect![[r#" | 382 | expect![[r#" |
383 | kw fn | 383 | kw fn |
384 | kw use | 384 | kw use |
@@ -406,7 +406,7 @@ fn quux() -> i32 { | |||
406 | #[test] | 406 | #[test] |
407 | fn test_keywords_after_unsafe_in_item_list() { | 407 | fn test_keywords_after_unsafe_in_item_list() { |
408 | check( | 408 | check( |
409 | r"unsafe <|>", | 409 | r"unsafe $0", |
410 | expect![[r#" | 410 | expect![[r#" |
411 | kw fn | 411 | kw fn |
412 | kw trait | 412 | kw trait |
@@ -418,7 +418,7 @@ fn quux() -> i32 { | |||
418 | #[test] | 418 | #[test] |
419 | fn test_keywords_after_unsafe_in_block_expr() { | 419 | fn test_keywords_after_unsafe_in_block_expr() { |
420 | check( | 420 | check( |
421 | r"fn my_fn() { unsafe <|> }", | 421 | r"fn my_fn() { unsafe $0 }", |
422 | expect![[r#" | 422 | expect![[r#" |
423 | kw fn | 423 | kw fn |
424 | kw trait | 424 | kw trait |
@@ -430,19 +430,19 @@ fn quux() -> i32 { | |||
430 | #[test] | 430 | #[test] |
431 | fn test_mut_in_ref_and_in_fn_parameters_list() { | 431 | fn test_mut_in_ref_and_in_fn_parameters_list() { |
432 | check( | 432 | check( |
433 | r"fn my_fn(&<|>) {}", | 433 | r"fn my_fn(&$0) {}", |
434 | expect![[r#" | 434 | expect![[r#" |
435 | kw mut | 435 | kw mut |
436 | "#]], | 436 | "#]], |
437 | ); | 437 | ); |
438 | check( | 438 | check( |
439 | r"fn my_fn(<|>) {}", | 439 | r"fn my_fn($0) {}", |
440 | expect![[r#" | 440 | expect![[r#" |
441 | kw mut | 441 | kw mut |
442 | "#]], | 442 | "#]], |
443 | ); | 443 | ); |
444 | check( | 444 | check( |
445 | r"fn my_fn() { let &<|> }", | 445 | r"fn my_fn() { let &$0 }", |
446 | expect![[r#" | 446 | expect![[r#" |
447 | kw mut | 447 | kw mut |
448 | "#]], | 448 | "#]], |
@@ -452,13 +452,13 @@ fn quux() -> i32 { | |||
452 | #[test] | 452 | #[test] |
453 | fn test_where_keyword() { | 453 | fn test_where_keyword() { |
454 | check( | 454 | check( |
455 | r"trait A <|>", | 455 | r"trait A $0", |
456 | expect![[r#" | 456 | expect![[r#" |
457 | kw where | 457 | kw where |
458 | "#]], | 458 | "#]], |
459 | ); | 459 | ); |
460 | check( | 460 | check( |
461 | r"impl A <|>", | 461 | r"impl A $0", |
462 | expect![[r#" | 462 | expect![[r#" |
463 | kw where | 463 | kw where |
464 | "#]], | 464 | "#]], |
@@ -471,7 +471,7 @@ fn quux() -> i32 { | |||
471 | check( | 471 | check( |
472 | r#" | 472 | r#" |
473 | fn test() { | 473 | fn test() { |
474 | let x = 2; // A comment<|> | 474 | let x = 2; // A comment$0 |
475 | } | 475 | } |
476 | "#, | 476 | "#, |
477 | expect![[""]], | 477 | expect![[""]], |
@@ -479,7 +479,7 @@ fn test() { | |||
479 | check( | 479 | check( |
480 | r#" | 480 | r#" |
481 | /* | 481 | /* |
482 | Some multi-line comment<|> | 482 | Some multi-line comment$0 |
483 | */ | 483 | */ |
484 | "#, | 484 | "#, |
485 | expect![[""]], | 485 | expect![[""]], |
@@ -487,7 +487,7 @@ Some multi-line comment<|> | |||
487 | check( | 487 | check( |
488 | r#" | 488 | r#" |
489 | /// Some doc comment | 489 | /// Some doc comment |
490 | /// let test<|> = 1 | 490 | /// let test$0 = 1 |
491 | "#, | 491 | "#, |
492 | expect![[""]], | 492 | expect![[""]], |
493 | ); | 493 | ); |
@@ -501,7 +501,7 @@ Some multi-line comment<|> | |||
501 | use std::future::*; | 501 | use std::future::*; |
502 | struct A {} | 502 | struct A {} |
503 | impl Future for A {} | 503 | impl Future for A {} |
504 | fn foo(a: A) { a.<|> } | 504 | fn foo(a: A) { a.$0 } |
505 | 505 | ||
506 | //- /std/lib.rs crate:std | 506 | //- /std/lib.rs crate:std |
507 | pub mod future { | 507 | pub mod future { |
@@ -520,7 +520,7 @@ pub mod future { | |||
520 | use std::future::*; | 520 | use std::future::*; |
521 | fn foo() { | 521 | fn foo() { |
522 | let a = async {}; | 522 | let a = async {}; |
523 | a.<|> | 523 | a.$0 |
524 | } | 524 | } |
525 | 525 | ||
526 | //- /std/lib.rs crate:std | 526 | //- /std/lib.rs crate:std |
@@ -540,7 +540,7 @@ pub mod future { | |||
540 | #[test] | 540 | #[test] |
541 | fn after_let() { | 541 | fn after_let() { |
542 | check( | 542 | check( |
543 | r#"fn main() { let _ = <|> }"#, | 543 | r#"fn main() { let _ = $0 }"#, |
544 | expect![[r#" | 544 | expect![[r#" |
545 | kw match | 545 | kw match |
546 | kw while | 546 | kw while |
@@ -557,7 +557,7 @@ pub mod future { | |||
557 | check( | 557 | check( |
558 | r#" | 558 | r#" |
559 | struct Foo { | 559 | struct Foo { |
560 | <|> | 560 | $0 |
561 | pub f: i32, | 561 | pub f: i32, |
562 | } | 562 | } |
563 | "#, | 563 | "#, |
@@ -578,7 +578,7 @@ struct Foo { | |||
578 | } | 578 | } |
579 | fn foo() { | 579 | fn foo() { |
580 | Foo { | 580 | Foo { |
581 | <|> | 581 | $0 |
582 | } | 582 | } |
583 | } | 583 | } |
584 | "#, | 584 | "#, |
@@ -595,7 +595,7 @@ struct Foo { | |||
595 | } | 595 | } |
596 | fn foo() { | 596 | fn foo() { |
597 | Foo { | 597 | Foo { |
598 | f: <|> | 598 | f: $0 |
599 | } | 599 | } |
600 | } | 600 | } |
601 | "#, | 601 | "#, |
diff --git a/crates/completion/src/completions/macro_in_item_position.rs b/crates/completion/src/completions/macro_in_item_position.rs index 82884a181..2be299ac2 100644 --- a/crates/completion/src/completions/macro_in_item_position.rs +++ b/crates/completion/src/completions/macro_in_item_position.rs | |||
@@ -31,7 +31,7 @@ mod tests { | |||
31 | macro_rules! foo { () => {} } | 31 | macro_rules! foo { () => {} } |
32 | fn foo() {} | 32 | fn foo() {} |
33 | 33 | ||
34 | <|> | 34 | $0 |
35 | "#, | 35 | "#, |
36 | expect![[r#" | 36 | expect![[r#" |
37 | ma foo!(…) macro_rules! foo | 37 | ma foo!(…) macro_rules! foo |
diff --git a/crates/completion/src/completions/mod_.rs b/crates/completion/src/completions/mod_.rs index f77864b77..00e951ca9 100644 --- a/crates/completion/src/completions/mod_.rs +++ b/crates/completion/src/completions/mod_.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | //! Completes mod declarations. | 1 | //! Completes mod declarations. |
2 | 2 | ||
3 | use std::iter; | ||
4 | |||
3 | use hir::{Module, ModuleSource}; | 5 | use hir::{Module, ModuleSource}; |
4 | use ide_db::base_db::{SourceDatabaseExt, VfsPath}; | 6 | use ide_db::base_db::{SourceDatabaseExt, VfsPath}; |
5 | use ide_db::RootDatabase; | 7 | use ide_db::RootDatabase; |
@@ -9,12 +11,11 @@ use crate::{CompletionItem, CompletionItemKind}; | |||
9 | 11 | ||
10 | use crate::{context::CompletionContext, item::CompletionKind, Completions}; | 12 | use crate::{context::CompletionContext, item::CompletionKind, Completions}; |
11 | 13 | ||
12 | /// Complete mod declaration, i.e. `mod <|> ;` | 14 | /// Complete mod declaration, i.e. `mod $0 ;` |
13 | pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { | 15 | pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { |
14 | let mod_under_caret = match &ctx.mod_declaration_under_caret { | 16 | let mod_under_caret = match &ctx.mod_declaration_under_caret { |
15 | Some(mod_under_caret) if mod_under_caret.item_list().is_some() => return None, | 17 | Some(mod_under_caret) if mod_under_caret.item_list().is_none() => mod_under_caret, |
16 | Some(mod_under_caret) => mod_under_caret, | 18 | _ => return None, |
17 | None => return None, | ||
18 | }; | 19 | }; |
19 | 20 | ||
20 | let _p = profile::span("completion::complete_mod"); | 21 | let _p = profile::span("completion::complete_mod"); |
@@ -49,9 +50,13 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op | |||
49 | .filter_map(|submodule_file| { | 50 | .filter_map(|submodule_file| { |
50 | let submodule_path = source_root.path_for_file(&submodule_file)?; | 51 | let submodule_path = source_root.path_for_file(&submodule_file)?; |
51 | let directory_with_submodule = submodule_path.parent()?; | 52 | let directory_with_submodule = submodule_path.parent()?; |
52 | match submodule_path.name_and_extension()? { | 53 | let (name, ext) = submodule_path.name_and_extension()?; |
53 | ("lib", Some("rs")) | ("main", Some("rs")) => None, | 54 | if ext != Some("rs") { |
54 | ("mod", Some("rs")) => { | 55 | return None; |
56 | } | ||
57 | match name { | ||
58 | "lib" | "main" => None, | ||
59 | "mod" => { | ||
55 | if directory_with_submodule.parent()? == directory_to_look_for_submodules { | 60 | if directory_with_submodule.parent()? == directory_to_look_for_submodules { |
56 | match directory_with_submodule.name_and_extension()? { | 61 | match directory_with_submodule.name_and_extension()? { |
57 | (directory_name, None) => Some(directory_name.to_owned()), | 62 | (directory_name, None) => Some(directory_name.to_owned()), |
@@ -61,9 +66,7 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op | |||
61 | None | 66 | None |
62 | } | 67 | } |
63 | } | 68 | } |
64 | (file_name, Some("rs")) | 69 | file_name if directory_with_submodule == directory_to_look_for_submodules => { |
65 | if directory_with_submodule == directory_to_look_for_submodules => | ||
66 | { | ||
67 | Some(file_name.to_owned()) | 70 | Some(file_name.to_owned()) |
68 | } | 71 | } |
69 | _ => None, | 72 | _ => None, |
@@ -73,7 +76,7 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op | |||
73 | .for_each(|submodule_name| { | 76 | .for_each(|submodule_name| { |
74 | let mut label = submodule_name; | 77 | let mut label = submodule_name; |
75 | if mod_under_caret.semicolon_token().is_none() { | 78 | if mod_under_caret.semicolon_token().is_none() { |
76 | label.push(';') | 79 | label.push(';'); |
77 | } | 80 | } |
78 | CompletionItem::new(CompletionKind::Magic, ctx.source_range(), &label) | 81 | CompletionItem::new(CompletionKind::Magic, ctx.source_range(), &label) |
79 | .kind(CompletionItemKind::Module) | 82 | .kind(CompletionItemKind::Module) |
@@ -89,11 +92,13 @@ fn directory_to_look_for_submodules( | |||
89 | module_file_path: &VfsPath, | 92 | module_file_path: &VfsPath, |
90 | ) -> Option<VfsPath> { | 93 | ) -> Option<VfsPath> { |
91 | let directory_with_module_path = module_file_path.parent()?; | 94 | let directory_with_module_path = module_file_path.parent()?; |
92 | let base_directory = match module_file_path.name_and_extension()? { | 95 | let (name, ext) = module_file_path.name_and_extension()?; |
93 | ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => { | 96 | if ext != Some("rs") { |
94 | Some(directory_with_module_path) | 97 | return None; |
95 | } | 98 | } |
96 | (regular_rust_file_name, Some("rs")) => { | 99 | let base_directory = match name { |
100 | "mod" | "lib" | "main" => Some(directory_with_module_path), | ||
101 | regular_rust_file_name => { | ||
97 | if matches!( | 102 | if matches!( |
98 | ( | 103 | ( |
99 | directory_with_module_path | 104 | directory_with_module_path |
@@ -110,37 +115,25 @@ fn directory_to_look_for_submodules( | |||
110 | directory_with_module_path.join(regular_rust_file_name) | 115 | directory_with_module_path.join(regular_rust_file_name) |
111 | } | 116 | } |
112 | } | 117 | } |
113 | _ => None, | ||
114 | }?; | 118 | }?; |
115 | 119 | ||
116 | let mut resulting_path = base_directory; | 120 | module_chain_to_containing_module_file(module, db) |
117 | for module in module_chain_to_containing_module_file(module, db) { | 121 | .into_iter() |
118 | if let Some(name) = module.name(db) { | 122 | .filter_map(|module| module.name(db)) |
119 | resulting_path = resulting_path.join(&name.to_string())?; | 123 | .try_fold(base_directory, |path, name| path.join(&name.to_string())) |
120 | } | ||
121 | } | ||
122 | |||
123 | Some(resulting_path) | ||
124 | } | 124 | } |
125 | 125 | ||
126 | fn module_chain_to_containing_module_file( | 126 | fn module_chain_to_containing_module_file( |
127 | current_module: Module, | 127 | current_module: Module, |
128 | db: &RootDatabase, | 128 | db: &RootDatabase, |
129 | ) -> Vec<Module> { | 129 | ) -> Vec<Module> { |
130 | let mut path = Vec::new(); | 130 | let mut path = |
131 | 131 | iter::successors(Some(current_module), |current_module| current_module.parent(db)) | |
132 | let mut current_module = Some(current_module); | 132 | .take_while(|current_module| { |
133 | while let Some(ModuleSource::Module(_)) = | 133 | matches!(current_module.definition_source(db).value, ModuleSource::Module(_)) |
134 | current_module.map(|module| module.definition_source(db).value) | 134 | }) |
135 | { | 135 | .collect::<Vec<_>>(); |
136 | if let Some(module) = current_module { | 136 | path.reverse(); |
137 | path.insert(0, module); | ||
138 | current_module = module.parent(db); | ||
139 | } else { | ||
140 | current_module = None; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | path | 137 | path |
145 | } | 138 | } |
146 | 139 | ||
@@ -159,7 +152,7 @@ mod tests { | |||
159 | check( | 152 | check( |
160 | r#" | 153 | r#" |
161 | //- /lib.rs | 154 | //- /lib.rs |
162 | mod <|> | 155 | mod $0 |
163 | //- /foo.rs | 156 | //- /foo.rs |
164 | fn foo() {} | 157 | fn foo() {} |
165 | //- /foo/ignored_foo.rs | 158 | //- /foo/ignored_foo.rs |
@@ -181,7 +174,7 @@ mod tests { | |||
181 | check( | 174 | check( |
182 | r#" | 175 | r#" |
183 | //- /lib.rs | 176 | //- /lib.rs |
184 | mod <|> { | 177 | mod $0 { |
185 | 178 | ||
186 | } | 179 | } |
187 | //- /foo.rs | 180 | //- /foo.rs |
@@ -196,7 +189,7 @@ mod tests { | |||
196 | check( | 189 | check( |
197 | r#" | 190 | r#" |
198 | //- /main.rs | 191 | //- /main.rs |
199 | mod <|> | 192 | mod $0 |
200 | //- /foo.rs | 193 | //- /foo.rs |
201 | fn foo() {} | 194 | fn foo() {} |
202 | //- /foo/ignored_foo.rs | 195 | //- /foo/ignored_foo.rs |
@@ -219,7 +212,7 @@ mod tests { | |||
219 | r#" | 212 | r#" |
220 | //- /main.rs | 213 | //- /main.rs |
221 | mod tests { | 214 | mod tests { |
222 | mod <|>; | 215 | mod $0; |
223 | } | 216 | } |
224 | //- /tests/foo.rs | 217 | //- /tests/foo.rs |
225 | fn foo() {} | 218 | fn foo() {} |
@@ -237,7 +230,7 @@ mod tests { | |||
237 | //- /lib.rs | 230 | //- /lib.rs |
238 | mod foo; | 231 | mod foo; |
239 | //- /foo.rs | 232 | //- /foo.rs |
240 | mod <|>; | 233 | mod $0; |
241 | //- /foo/bar.rs | 234 | //- /foo/bar.rs |
242 | fn bar() {} | 235 | fn bar() {} |
243 | //- /foo/bar/ignored_bar.rs | 236 | //- /foo/bar/ignored_bar.rs |
@@ -262,7 +255,7 @@ mod tests { | |||
262 | mod foo; | 255 | mod foo; |
263 | //- /foo.rs | 256 | //- /foo.rs |
264 | mod bar { | 257 | mod bar { |
265 | mod <|> | 258 | mod $0 |
266 | } | 259 | } |
267 | //- /foo/bar/baz.rs | 260 | //- /foo/bar/baz.rs |
268 | fn baz() {} | 261 | fn baz() {} |
@@ -288,7 +281,7 @@ mod tests { | |||
288 | // //- /src/bin.rs | 281 | // //- /src/bin.rs |
289 | // fn main() {} | 282 | // fn main() {} |
290 | // //- /src/bin/foo.rs | 283 | // //- /src/bin/foo.rs |
291 | // mod <|> | 284 | // mod $0 |
292 | // //- /src/bin/bar.rs | 285 | // //- /src/bin/bar.rs |
293 | // fn bar() {} | 286 | // fn bar() {} |
294 | // //- /src/bin/bar/bar_ignored.rs | 287 | // //- /src/bin/bar/bar_ignored.rs |
@@ -307,7 +300,7 @@ mod tests { | |||
307 | //- /src/bin.rs crate:main | 300 | //- /src/bin.rs crate:main |
308 | fn main() {} | 301 | fn main() {} |
309 | //- /src/bin/foo.rs | 302 | //- /src/bin/foo.rs |
310 | mod <|> | 303 | mod $0 |
311 | //- /src/bin/bar.rs | 304 | //- /src/bin/bar.rs |
312 | mod foo; | 305 | mod foo; |
313 | fn bar() {} | 306 | fn bar() {} |
diff --git a/crates/completion/src/completions/pattern.rs b/crates/completion/src/completions/pattern.rs index eee31098d..595160ff5 100644 --- a/crates/completion/src/completions/pattern.rs +++ b/crates/completion/src/completions/pattern.rs | |||
@@ -71,7 +71,7 @@ static FOO: E = E::X; | |||
71 | struct Bar { f: u32 } | 71 | struct Bar { f: u32 } |
72 | 72 | ||
73 | fn foo() { | 73 | fn foo() { |
74 | match E::X { <|> } | 74 | match E::X { $0 } |
75 | } | 75 | } |
76 | "#, | 76 | "#, |
77 | expect![[r#" | 77 | expect![[r#" |
@@ -92,7 +92,7 @@ macro_rules! m { ($e:expr) => { $e } } | |||
92 | enum E { X } | 92 | enum E { X } |
93 | 93 | ||
94 | fn foo() { | 94 | fn foo() { |
95 | m!(match E::X { <|> }) | 95 | m!(match E::X { $0 }) |
96 | } | 96 | } |
97 | "#, | 97 | "#, |
98 | expect![[r#" | 98 | expect![[r#" |
@@ -115,7 +115,7 @@ static FOO: E = E::X; | |||
115 | struct Bar { f: u32 } | 115 | struct Bar { f: u32 } |
116 | 116 | ||
117 | fn foo() { | 117 | fn foo() { |
118 | let <|> | 118 | let $0 |
119 | } | 119 | } |
120 | "#, | 120 | "#, |
121 | expect![[r#" | 121 | expect![[r#" |
@@ -133,7 +133,7 @@ enum E { X } | |||
133 | static FOO: E = E::X; | 133 | static FOO: E = E::X; |
134 | struct Bar { f: u32 } | 134 | struct Bar { f: u32 } |
135 | 135 | ||
136 | fn foo(<|>) { | 136 | fn foo($0) { |
137 | } | 137 | } |
138 | "#, | 138 | "#, |
139 | expect![[r#" | 139 | expect![[r#" |
@@ -149,7 +149,7 @@ fn foo(<|>) { | |||
149 | struct Bar { f: u32 } | 149 | struct Bar { f: u32 } |
150 | 150 | ||
151 | fn foo() { | 151 | fn foo() { |
152 | let <|> | 152 | let $0 |
153 | } | 153 | } |
154 | "#, | 154 | "#, |
155 | expect![[r#" | 155 | expect![[r#" |
@@ -165,7 +165,7 @@ fn foo() { | |||
165 | struct Foo { bar: String, baz: String } | 165 | struct Foo { bar: String, baz: String } |
166 | struct Bar(String, String); | 166 | struct Bar(String, String); |
167 | struct Baz; | 167 | struct Baz; |
168 | fn outer(<|>) {} | 168 | fn outer($0) {} |
169 | "#, | 169 | "#, |
170 | expect![[r#" | 170 | expect![[r#" |
171 | bn Foo Foo { bar$1, baz$2 }: Foo$0 | 171 | bn Foo Foo { bar$1, baz$2 }: Foo$0 |
@@ -182,7 +182,7 @@ struct Foo { bar: String, baz: String } | |||
182 | struct Bar(String, String); | 182 | struct Bar(String, String); |
183 | struct Baz; | 183 | struct Baz; |
184 | fn outer() { | 184 | fn outer() { |
185 | let <|> | 185 | let $0 |
186 | } | 186 | } |
187 | "#, | 187 | "#, |
188 | expect![[r#" | 188 | expect![[r#" |
@@ -201,7 +201,7 @@ struct Bar(String, String); | |||
201 | struct Baz; | 201 | struct Baz; |
202 | fn outer() { | 202 | fn outer() { |
203 | match () { | 203 | match () { |
204 | <|> | 204 | $0 |
205 | } | 205 | } |
206 | } | 206 | } |
207 | "#, | 207 | "#, |
@@ -225,7 +225,7 @@ use foo::*; | |||
225 | 225 | ||
226 | fn outer() { | 226 | fn outer() { |
227 | match () { | 227 | match () { |
228 | <|> | 228 | $0 |
229 | } | 229 | } |
230 | } | 230 | } |
231 | "#, | 231 | "#, |
@@ -244,7 +244,7 @@ fn outer() { | |||
244 | struct Foo(i32); | 244 | struct Foo(i32); |
245 | fn main() { | 245 | fn main() { |
246 | match Foo(92) { | 246 | match Foo(92) { |
247 | <|>(92) => (), | 247 | $0(92) => (), |
248 | } | 248 | } |
249 | } | 249 | } |
250 | "#, | 250 | "#, |
diff --git a/crates/completion/src/completions/postfix.rs b/crates/completion/src/completions/postfix.rs index 3883d6d21..9c34ed0b6 100644 --- a/crates/completion/src/completions/postfix.rs +++ b/crates/completion/src/completions/postfix.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | //! Postfix completions, like `Ok(10).ifl<|>` => `if let Ok() = Ok(10) { <|> }`. | 1 | //! Postfix completions, like `Ok(10).ifl$0` => `if let Ok() = Ok(10) { $0 }`. |
2 | 2 | ||
3 | mod format_like; | 3 | mod format_like; |
4 | 4 | ||
5 | use ide_db::ty_filter::TryEnum; | 5 | use ide_db::{helpers::SnippetCap, ty_filter::TryEnum}; |
6 | use syntax::{ | 6 | use syntax::{ |
7 | ast::{self, AstNode, AstToken}, | 7 | ast::{self, AstNode, AstToken}, |
8 | SyntaxKind::{BLOCK_EXPR, EXPR_STMT}, | 8 | SyntaxKind::{BLOCK_EXPR, EXPR_STMT}, |
@@ -10,9 +10,8 @@ use syntax::{ | |||
10 | }; | 10 | }; |
11 | use text_edit::TextEdit; | 11 | use text_edit::TextEdit; |
12 | 12 | ||
13 | use self::format_like::add_format_like_completions; | ||
14 | use crate::{ | 13 | use crate::{ |
15 | config::SnippetCap, | 14 | completions::postfix::format_like::add_format_like_completions, |
16 | context::CompletionContext, | 15 | context::CompletionContext, |
17 | item::{Builder, CompletionKind}, | 16 | item::{Builder, CompletionKind}, |
18 | CompletionItem, CompletionItemKind, Completions, | 17 | CompletionItem, CompletionItemKind, Completions, |
@@ -36,11 +35,14 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
36 | None => return, | 35 | None => return, |
37 | }; | 36 | }; |
38 | 37 | ||
38 | let ref_removed_ty = | ||
39 | std::iter::successors(Some(receiver_ty.clone()), |ty| ty.remove_ref()).last().unwrap(); | ||
40 | |||
39 | let cap = match ctx.config.snippet_cap { | 41 | let cap = match ctx.config.snippet_cap { |
40 | Some(it) => it, | 42 | Some(it) => it, |
41 | None => return, | 43 | None => return, |
42 | }; | 44 | }; |
43 | let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty); | 45 | let try_enum = TryEnum::from_ty(&ctx.sema, &ref_removed_ty); |
44 | if let Some(try_enum) = &try_enum { | 46 | if let Some(try_enum) = &try_enum { |
45 | match try_enum { | 47 | match try_enum { |
46 | TryEnum::Result => { | 48 | TryEnum::Result => { |
@@ -311,7 +313,7 @@ mod tests { | |||
311 | r#" | 313 | r#" |
312 | fn main() { | 314 | fn main() { |
313 | let bar = true; | 315 | let bar = true; |
314 | bar.<|> | 316 | bar.$0 |
315 | } | 317 | } |
316 | "#, | 318 | "#, |
317 | expect![[r#" | 319 | expect![[r#" |
@@ -343,7 +345,7 @@ fn foo(elt: bool) -> bool { | |||
343 | 345 | ||
344 | fn main() { | 346 | fn main() { |
345 | let bar = true; | 347 | let bar = true; |
346 | foo(bar.<|>) | 348 | foo(bar.$0) |
347 | } | 349 | } |
348 | "#, | 350 | "#, |
349 | expect![[r#" | 351 | expect![[r#" |
@@ -369,7 +371,7 @@ fn main() { | |||
369 | r#" | 371 | r#" |
370 | fn main() { | 372 | fn main() { |
371 | let bar: u8 = 12; | 373 | let bar: u8 = 12; |
372 | bar.<|> | 374 | bar.$0 |
373 | } | 375 | } |
374 | "#, | 376 | "#, |
375 | expect![[r#" | 377 | expect![[r#" |
@@ -393,7 +395,7 @@ fn main() { | |||
393 | check( | 395 | check( |
394 | r#" | 396 | r#" |
395 | fn main() { | 397 | fn main() { |
396 | baz.l<|> | 398 | baz.l$0 |
397 | res | 399 | res |
398 | } | 400 | } |
399 | "#, | 401 | "#, |
@@ -425,7 +427,7 @@ enum Option<T> { Some(T), None } | |||
425 | 427 | ||
426 | fn main() { | 428 | fn main() { |
427 | let bar = Option::Some(true); | 429 | let bar = Option::Some(true); |
428 | bar.<|> | 430 | bar.$0 |
429 | } | 431 | } |
430 | "#, | 432 | "#, |
431 | r#" | 433 | r#" |
@@ -450,7 +452,7 @@ enum Result<T, E> { Ok(T), Err(E) } | |||
450 | 452 | ||
451 | fn main() { | 453 | fn main() { |
452 | let bar = Result::Ok(true); | 454 | let bar = Result::Ok(true); |
453 | bar.<|> | 455 | bar.$0 |
454 | } | 456 | } |
455 | "#, | 457 | "#, |
456 | r#" | 458 | r#" |
@@ -469,7 +471,7 @@ fn main() { | |||
469 | 471 | ||
470 | #[test] | 472 | #[test] |
471 | fn postfix_completion_works_for_ambiguous_float_literal() { | 473 | fn postfix_completion_works_for_ambiguous_float_literal() { |
472 | check_edit("refm", r#"fn main() { 42.<|> }"#, r#"fn main() { &mut 42 }"#) | 474 | check_edit("refm", r#"fn main() { 42.$0 }"#, r#"fn main() { &mut 42 }"#) |
473 | } | 475 | } |
474 | 476 | ||
475 | #[test] | 477 | #[test] |
@@ -480,7 +482,7 @@ fn main() { | |||
480 | macro_rules! m { ($e:expr) => { $e } } | 482 | macro_rules! m { ($e:expr) => { $e } } |
481 | fn main() { | 483 | fn main() { |
482 | let bar: u8 = 12; | 484 | let bar: u8 = 12; |
483 | m!(bar.d<|>) | 485 | m!(bar.d$0) |
484 | } | 486 | } |
485 | "#, | 487 | "#, |
486 | r#" | 488 | r#" |
@@ -495,55 +497,68 @@ fn main() { | |||
495 | 497 | ||
496 | #[test] | 498 | #[test] |
497 | fn postfix_completion_for_references() { | 499 | fn postfix_completion_for_references() { |
498 | check_edit("dbg", r#"fn main() { &&42.<|> }"#, r#"fn main() { dbg!(&&42) }"#); | 500 | check_edit("dbg", r#"fn main() { &&42.$0 }"#, r#"fn main() { dbg!(&&42) }"#); |
499 | check_edit("refm", r#"fn main() { &&42.<|> }"#, r#"fn main() { &&&mut 42 }"#); | 501 | check_edit("refm", r#"fn main() { &&42.$0 }"#, r#"fn main() { &&&mut 42 }"#); |
502 | check_edit( | ||
503 | "ifl", | ||
504 | r#" | ||
505 | enum Option<T> { Some(T), None } | ||
506 | |||
507 | fn main() { | ||
508 | let bar = &Option::Some(true); | ||
509 | bar.$0 | ||
510 | } | ||
511 | "#, | ||
512 | r#" | ||
513 | enum Option<T> { Some(T), None } | ||
514 | |||
515 | fn main() { | ||
516 | let bar = &Option::Some(true); | ||
517 | if let Some($1) = bar { | ||
518 | $0 | ||
519 | } | ||
520 | } | ||
521 | "#, | ||
522 | ) | ||
500 | } | 523 | } |
501 | 524 | ||
502 | #[test] | 525 | #[test] |
503 | fn postfix_completion_for_format_like_strings() { | 526 | fn postfix_completion_for_format_like_strings() { |
504 | check_edit( | 527 | check_edit( |
505 | "format", | 528 | "format", |
506 | r#"fn main() { "{some_var:?}".<|> }"#, | 529 | r#"fn main() { "{some_var:?}".$0 }"#, |
507 | r#"fn main() { format!("{:?}", some_var) }"#, | 530 | r#"fn main() { format!("{:?}", some_var) }"#, |
508 | ); | 531 | ); |
509 | check_edit( | 532 | check_edit( |
510 | "panic", | 533 | "panic", |
511 | r#"fn main() { "Panic with {a}".<|> }"#, | 534 | r#"fn main() { "Panic with {a}".$0 }"#, |
512 | r#"fn main() { panic!("Panic with {}", a) }"#, | 535 | r#"fn main() { panic!("Panic with {}", a) }"#, |
513 | ); | 536 | ); |
514 | check_edit( | 537 | check_edit( |
515 | "println", | 538 | "println", |
516 | r#"fn main() { "{ 2+2 } { SomeStruct { val: 1, other: 32 } :?}".<|> }"#, | 539 | r#"fn main() { "{ 2+2 } { SomeStruct { val: 1, other: 32 } :?}".$0 }"#, |
517 | r#"fn main() { println!("{} {:?}", 2+2, SomeStruct { val: 1, other: 32 }) }"#, | 540 | r#"fn main() { println!("{} {:?}", 2+2, SomeStruct { val: 1, other: 32 }) }"#, |
518 | ); | 541 | ); |
519 | check_edit( | 542 | check_edit( |
520 | "loge", | 543 | "loge", |
521 | r#"fn main() { "{2+2}".<|> }"#, | 544 | r#"fn main() { "{2+2}".$0 }"#, |
522 | r#"fn main() { log::error!("{}", 2+2) }"#, | 545 | r#"fn main() { log::error!("{}", 2+2) }"#, |
523 | ); | 546 | ); |
524 | check_edit( | 547 | check_edit( |
525 | "logt", | 548 | "logt", |
526 | r#"fn main() { "{2+2}".<|> }"#, | 549 | r#"fn main() { "{2+2}".$0 }"#, |
527 | r#"fn main() { log::trace!("{}", 2+2) }"#, | 550 | r#"fn main() { log::trace!("{}", 2+2) }"#, |
528 | ); | 551 | ); |
529 | check_edit( | 552 | check_edit( |
530 | "logd", | 553 | "logd", |
531 | r#"fn main() { "{2+2}".<|> }"#, | 554 | r#"fn main() { "{2+2}".$0 }"#, |
532 | r#"fn main() { log::debug!("{}", 2+2) }"#, | 555 | r#"fn main() { log::debug!("{}", 2+2) }"#, |
533 | ); | 556 | ); |
534 | check_edit( | 557 | check_edit("logi", r#"fn main() { "{2+2}".$0 }"#, r#"fn main() { log::info!("{}", 2+2) }"#); |
535 | "logi", | 558 | check_edit("logw", r#"fn main() { "{2+2}".$0 }"#, r#"fn main() { log::warn!("{}", 2+2) }"#); |
536 | r#"fn main() { "{2+2}".<|> }"#, | ||
537 | r#"fn main() { log::info!("{}", 2+2) }"#, | ||
538 | ); | ||
539 | check_edit( | ||
540 | "logw", | ||
541 | r#"fn main() { "{2+2}".<|> }"#, | ||
542 | r#"fn main() { log::warn!("{}", 2+2) }"#, | ||
543 | ); | ||
544 | check_edit( | 559 | check_edit( |
545 | "loge", | 560 | "loge", |
546 | r#"fn main() { "{2+2}".<|> }"#, | 561 | r#"fn main() { "{2+2}".$0 }"#, |
547 | r#"fn main() { log::error!("{}", 2+2) }"#, | 562 | r#"fn main() { log::error!("{}", 2+2) }"#, |
548 | ); | 563 | ); |
549 | } | 564 | } |
diff --git a/crates/completion/src/completions/postfix/format_like.rs b/crates/completion/src/completions/postfix/format_like.rs index def4b13fb..3afc63021 100644 --- a/crates/completion/src/completions/postfix/format_like.rs +++ b/crates/completion/src/completions/postfix/format_like.rs | |||
@@ -14,12 +14,11 @@ | |||
14 | // + `logw` -> `log::warn!(...)` | 14 | // + `logw` -> `log::warn!(...)` |
15 | // + `loge` -> `log::error!(...)` | 15 | // + `loge` -> `log::error!(...)` |
16 | 16 | ||
17 | use crate::{ | 17 | use ide_db::helpers::SnippetCap; |
18 | completions::postfix::postfix_snippet, config::SnippetCap, context::CompletionContext, | ||
19 | Completions, | ||
20 | }; | ||
21 | use syntax::ast::{self, AstToken}; | 18 | use syntax::ast::{self, AstToken}; |
22 | 19 | ||
20 | use crate::{completions::postfix::postfix_snippet, context::CompletionContext, Completions}; | ||
21 | |||
23 | /// Mapping ("postfix completion item" => "macro to use") | 22 | /// Mapping ("postfix completion item" => "macro to use") |
24 | static KINDS: &[(&str, &str)] = &[ | 23 | static KINDS: &[(&str, &str)] = &[ |
25 | ("format", "format!"), | 24 | ("format", "format!"), |
diff --git a/crates/completion/src/completions/qualified_path.rs b/crates/completion/src/completions/qualified_path.rs index 882c4dcbc..fa9e6e810 100644 --- a/crates/completion/src/completions/qualified_path.rs +++ b/crates/completion/src/completions/qualified_path.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! Completion of paths, i.e. `some::prefix::<|>`. | 1 | //! Completion of paths, i.e. `some::prefix::$0`. |
2 | 2 | ||
3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; | 3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; |
4 | use rustc_hash::FxHashSet; | 4 | use rustc_hash::FxHashSet; |
@@ -38,7 +38,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
38 | if let ScopeDef::Unknown = def { | 38 | if let ScopeDef::Unknown = def { |
39 | if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { | 39 | if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { |
40 | if name_ref.syntax().text() == name.to_string().as_str() { | 40 | if name_ref.syntax().text() == name.to_string().as_str() { |
41 | // for `use self::foo<|>`, don't suggest `foo` as a completion | 41 | // for `use self::foo$0`, don't suggest `foo` as a completion |
42 | mark::hit!(dont_complete_current_use); | 42 | mark::hit!(dont_complete_current_use); |
43 | continue; | 43 | continue; |
44 | } | 44 | } |
@@ -173,7 +173,7 @@ mod tests { | |||
173 | #[test] | 173 | #[test] |
174 | fn dont_complete_current_use() { | 174 | fn dont_complete_current_use() { |
175 | mark::check!(dont_complete_current_use); | 175 | mark::check!(dont_complete_current_use); |
176 | check(r#"use self::foo<|>;"#, expect![[""]]); | 176 | check(r#"use self::foo$0;"#, expect![[""]]); |
177 | } | 177 | } |
178 | 178 | ||
179 | #[test] | 179 | #[test] |
@@ -181,7 +181,7 @@ mod tests { | |||
181 | check( | 181 | check( |
182 | r#" | 182 | r#" |
183 | mod foo { pub struct S; } | 183 | mod foo { pub struct S; } |
184 | use self::{foo::*, bar<|>}; | 184 | use self::{foo::*, bar$0}; |
185 | "#, | 185 | "#, |
186 | expect![[r#" | 186 | expect![[r#" |
187 | st S | 187 | st S |
@@ -192,18 +192,18 @@ use self::{foo::*, bar<|>}; | |||
192 | 192 | ||
193 | #[test] | 193 | #[test] |
194 | fn dont_complete_primitive_in_use() { | 194 | fn dont_complete_primitive_in_use() { |
195 | check_builtin(r#"use self::<|>;"#, expect![[""]]); | 195 | check_builtin(r#"use self::$0;"#, expect![[""]]); |
196 | } | 196 | } |
197 | 197 | ||
198 | #[test] | 198 | #[test] |
199 | fn dont_complete_primitive_in_module_scope() { | 199 | fn dont_complete_primitive_in_module_scope() { |
200 | check_builtin(r#"fn foo() { self::<|> }"#, expect![[""]]); | 200 | check_builtin(r#"fn foo() { self::$0 }"#, expect![[""]]); |
201 | } | 201 | } |
202 | 202 | ||
203 | #[test] | 203 | #[test] |
204 | fn completes_primitives() { | 204 | fn completes_primitives() { |
205 | check_builtin( | 205 | check_builtin( |
206 | r#"fn main() { let _: <|> = 92; }"#, | 206 | r#"fn main() { let _: $0 = 92; }"#, |
207 | expect![[r#" | 207 | expect![[r#" |
208 | bt u32 | 208 | bt u32 |
209 | bt bool | 209 | bt bool |
@@ -230,7 +230,7 @@ use self::{foo::*, bar<|>}; | |||
230 | fn completes_mod_with_same_name_as_function() { | 230 | fn completes_mod_with_same_name_as_function() { |
231 | check( | 231 | check( |
232 | r#" | 232 | r#" |
233 | use self::my::<|>; | 233 | use self::my::$0; |
234 | 234 | ||
235 | mod my { pub struct Bar; } | 235 | mod my { pub struct Bar; } |
236 | fn my() {} | 236 | fn my() {} |
@@ -245,7 +245,7 @@ fn my() {} | |||
245 | fn filters_visibility() { | 245 | fn filters_visibility() { |
246 | check( | 246 | check( |
247 | r#" | 247 | r#" |
248 | use self::my::<|>; | 248 | use self::my::$0; |
249 | 249 | ||
250 | mod my { | 250 | mod my { |
251 | struct Bar; | 251 | struct Bar; |
@@ -264,7 +264,7 @@ mod my { | |||
264 | fn completes_use_item_starting_with_self() { | 264 | fn completes_use_item_starting_with_self() { |
265 | check( | 265 | check( |
266 | r#" | 266 | r#" |
267 | use self::m::<|>; | 267 | use self::m::$0; |
268 | 268 | ||
269 | mod m { pub struct Bar; } | 269 | mod m { pub struct Bar; } |
270 | "#, | 270 | "#, |
@@ -282,7 +282,7 @@ mod m { pub struct Bar; } | |||
282 | mod foo; | 282 | mod foo; |
283 | struct Spam; | 283 | struct Spam; |
284 | //- /foo.rs | 284 | //- /foo.rs |
285 | use crate::Sp<|> | 285 | use crate::Sp$0 |
286 | "#, | 286 | "#, |
287 | expect![[r#" | 287 | expect![[r#" |
288 | md foo | 288 | md foo |
@@ -299,7 +299,7 @@ use crate::Sp<|> | |||
299 | mod foo; | 299 | mod foo; |
300 | struct Spam; | 300 | struct Spam; |
301 | //- /foo.rs | 301 | //- /foo.rs |
302 | use crate::{Sp<|>}; | 302 | use crate::{Sp$0}; |
303 | "#, | 303 | "#, |
304 | expect![[r#" | 304 | expect![[r#" |
305 | md foo | 305 | md foo |
@@ -320,7 +320,7 @@ pub mod bar { | |||
320 | } | 320 | } |
321 | } | 321 | } |
322 | //- /foo.rs | 322 | //- /foo.rs |
323 | use crate::{bar::{baz::Sp<|>}}; | 323 | use crate::{bar::{baz::Sp$0}}; |
324 | "#, | 324 | "#, |
325 | expect![[r#" | 325 | expect![[r#" |
326 | st Spam | 326 | st Spam |
@@ -333,7 +333,7 @@ use crate::{bar::{baz::Sp<|>}}; | |||
333 | check( | 333 | check( |
334 | r#" | 334 | r#" |
335 | enum E { Foo, Bar(i32) } | 335 | enum E { Foo, Bar(i32) } |
336 | fn foo() { let _ = E::<|> } | 336 | fn foo() { let _ = E::$0 } |
337 | "#, | 337 | "#, |
338 | expect![[r#" | 338 | expect![[r#" |
339 | ev Foo () | 339 | ev Foo () |
@@ -356,7 +356,7 @@ impl S { | |||
356 | type T = i32; | 356 | type T = i32; |
357 | } | 357 | } |
358 | 358 | ||
359 | fn foo() { let _ = S::<|> } | 359 | fn foo() { let _ = S::$0 } |
360 | "#, | 360 | "#, |
361 | expect![[r#" | 361 | expect![[r#" |
362 | fn a() fn a() | 362 | fn a() fn a() |
@@ -384,7 +384,7 @@ mod m { | |||
384 | } | 384 | } |
385 | } | 385 | } |
386 | 386 | ||
387 | fn foo() { let _ = S::<|> } | 387 | fn foo() { let _ = S::$0 } |
388 | "#, | 388 | "#, |
389 | expect![[r#" | 389 | expect![[r#" |
390 | fn public_method() pub(crate) fn public_method() | 390 | fn public_method() pub(crate) fn public_method() |
@@ -401,7 +401,7 @@ fn foo() { let _ = S::<|> } | |||
401 | enum E {}; | 401 | enum E {}; |
402 | impl E { fn m() { } } | 402 | impl E { fn m() { } } |
403 | 403 | ||
404 | fn foo() { let _ = E::<|> } | 404 | fn foo() { let _ = E::$0 } |
405 | "#, | 405 | "#, |
406 | expect![[r#" | 406 | expect![[r#" |
407 | fn m() fn m() | 407 | fn m() fn m() |
@@ -416,7 +416,7 @@ fn foo() { let _ = E::<|> } | |||
416 | union U {}; | 416 | union U {}; |
417 | impl U { fn m() { } } | 417 | impl U { fn m() { } } |
418 | 418 | ||
419 | fn foo() { let _ = U::<|> } | 419 | fn foo() { let _ = U::$0 } |
420 | "#, | 420 | "#, |
421 | expect![[r#" | 421 | expect![[r#" |
422 | fn m() fn m() | 422 | fn m() fn m() |
@@ -429,7 +429,7 @@ fn foo() { let _ = U::<|> } | |||
429 | check( | 429 | check( |
430 | r#" | 430 | r#" |
431 | //- /main.rs crate:main deps:foo | 431 | //- /main.rs crate:main deps:foo |
432 | use foo::<|>; | 432 | use foo::$0; |
433 | 433 | ||
434 | //- /foo/lib.rs crate:foo | 434 | //- /foo/lib.rs crate:foo |
435 | pub mod bar { pub struct S; } | 435 | pub mod bar { pub struct S; } |
@@ -446,7 +446,7 @@ pub mod bar { pub struct S; } | |||
446 | r#" | 446 | r#" |
447 | trait Trait { fn m(); } | 447 | trait Trait { fn m(); } |
448 | 448 | ||
449 | fn foo() { let _ = Trait::<|> } | 449 | fn foo() { let _ = Trait::$0 } |
450 | "#, | 450 | "#, |
451 | expect![[r#" | 451 | expect![[r#" |
452 | fn m() fn m() | 452 | fn m() fn m() |
@@ -463,7 +463,7 @@ trait Trait { fn m(); } | |||
463 | struct S; | 463 | struct S; |
464 | impl Trait for S {} | 464 | impl Trait for S {} |
465 | 465 | ||
466 | fn foo() { let _ = S::<|> } | 466 | fn foo() { let _ = S::$0 } |
467 | "#, | 467 | "#, |
468 | expect![[r#" | 468 | expect![[r#" |
469 | fn m() fn m() | 469 | fn m() fn m() |
@@ -480,7 +480,7 @@ trait Trait { fn m(); } | |||
480 | struct S; | 480 | struct S; |
481 | impl Trait for S {} | 481 | impl Trait for S {} |
482 | 482 | ||
483 | fn foo() { let _ = <S as Trait>::<|> } | 483 | fn foo() { let _ = <S as Trait>::$0 } |
484 | "#, | 484 | "#, |
485 | expect![[r#" | 485 | expect![[r#" |
486 | fn m() fn m() | 486 | fn m() fn m() |
@@ -506,7 +506,7 @@ trait Sub: Super { | |||
506 | fn submethod(&self) {} | 506 | fn submethod(&self) {} |
507 | } | 507 | } |
508 | 508 | ||
509 | fn foo<T: Sub>() { T::<|> } | 509 | fn foo<T: Sub>() { T::$0 } |
510 | "#, | 510 | "#, |
511 | expect![[r#" | 511 | expect![[r#" |
512 | ta SubTy type SubTy; | 512 | ta SubTy type SubTy; |
@@ -544,7 +544,7 @@ impl<T> Super for Wrap<T> {} | |||
544 | impl<T> Sub for Wrap<T> { | 544 | impl<T> Sub for Wrap<T> { |
545 | fn subfunc() { | 545 | fn subfunc() { |
546 | // Should be able to assume `Self: Sub + Super` | 546 | // Should be able to assume `Self: Sub + Super` |
547 | Self::<|> | 547 | Self::$0 |
548 | } | 548 | } |
549 | } | 549 | } |
550 | "#, | 550 | "#, |
@@ -570,7 +570,7 @@ impl S { fn foo() {} } | |||
570 | type T = S; | 570 | type T = S; |
571 | impl T { fn bar() {} } | 571 | impl T { fn bar() {} } |
572 | 572 | ||
573 | fn main() { T::<|>; } | 573 | fn main() { T::$0; } |
574 | "#, | 574 | "#, |
575 | expect![[r#" | 575 | expect![[r#" |
576 | fn foo() fn foo() | 576 | fn foo() fn foo() |
@@ -586,7 +586,7 @@ fn main() { T::<|>; } | |||
586 | #[macro_export] | 586 | #[macro_export] |
587 | macro_rules! foo { () => {} } | 587 | macro_rules! foo { () => {} } |
588 | 588 | ||
589 | fn main() { let _ = crate::<|> } | 589 | fn main() { let _ = crate::$0 } |
590 | "#, | 590 | "#, |
591 | expect![[r##" | 591 | expect![[r##" |
592 | fn main() fn main() | 592 | fn main() fn main() |
@@ -604,7 +604,7 @@ mod a { | |||
604 | const A: usize = 0; | 604 | const A: usize = 0; |
605 | mod b { | 605 | mod b { |
606 | const B: usize = 0; | 606 | const B: usize = 0; |
607 | mod c { use super::super::<|> } | 607 | mod c { use super::super::$0 } |
608 | } | 608 | } |
609 | } | 609 | } |
610 | "#, | 610 | "#, |
@@ -619,7 +619,7 @@ mod a { | |||
619 | fn completes_reexported_items_under_correct_name() { | 619 | fn completes_reexported_items_under_correct_name() { |
620 | check( | 620 | check( |
621 | r#" | 621 | r#" |
622 | fn foo() { self::m::<|> } | 622 | fn foo() { self::m::$0 } |
623 | 623 | ||
624 | mod m { | 624 | mod m { |
625 | pub use super::p::wrong_fn as right_fn; | 625 | pub use super::p::wrong_fn as right_fn; |
@@ -642,7 +642,7 @@ mod p { | |||
642 | check_edit( | 642 | check_edit( |
643 | "RightType", | 643 | "RightType", |
644 | r#" | 644 | r#" |
645 | fn foo() { self::m::<|> } | 645 | fn foo() { self::m::$0 } |
646 | 646 | ||
647 | mod m { | 647 | mod m { |
648 | pub use super::p::wrong_fn as right_fn; | 648 | pub use super::p::wrong_fn as right_fn; |
@@ -677,7 +677,7 @@ mod p { | |||
677 | check( | 677 | check( |
678 | r#" | 678 | r#" |
679 | macro_rules! m { ($e:expr) => { $e } } | 679 | macro_rules! m { ($e:expr) => { $e } } |
680 | fn main() { m!(self::f<|>); } | 680 | fn main() { m!(self::f$0); } |
681 | fn foo() {} | 681 | fn foo() {} |
682 | "#, | 682 | "#, |
683 | expect![[r#" | 683 | expect![[r#" |
@@ -691,7 +691,7 @@ fn foo() {} | |||
691 | fn function_mod_share_name() { | 691 | fn function_mod_share_name() { |
692 | check( | 692 | check( |
693 | r#" | 693 | r#" |
694 | fn foo() { self::m::<|> } | 694 | fn foo() { self::m::$0 } |
695 | 695 | ||
696 | mod m { | 696 | mod m { |
697 | pub mod z {} | 697 | pub mod z {} |
@@ -716,7 +716,7 @@ impl<K, V> HashMap<K, V, RandomState> { | |||
716 | pub fn new() -> HashMap<K, V, RandomState> { } | 716 | pub fn new() -> HashMap<K, V, RandomState> { } |
717 | } | 717 | } |
718 | fn foo() { | 718 | fn foo() { |
719 | HashMap::<|> | 719 | HashMap::$0 |
720 | } | 720 | } |
721 | "#, | 721 | "#, |
722 | expect![[r#" | 722 | expect![[r#" |
@@ -730,7 +730,7 @@ fn foo() { | |||
730 | check( | 730 | check( |
731 | r#" | 731 | r#" |
732 | mod foo { pub struct Foo; } | 732 | mod foo { pub struct Foo; } |
733 | #[foo::<|>] | 733 | #[foo::$0] |
734 | fn f() {} | 734 | fn f() {} |
735 | "#, | 735 | "#, |
736 | expect![[""]], | 736 | expect![[""]], |
@@ -749,7 +749,7 @@ fn foo( | |||
749 | } | 749 | } |
750 | 750 | ||
751 | fn main() { | 751 | fn main() { |
752 | fo<|> | 752 | fo$0 |
753 | } | 753 | } |
754 | "#, | 754 | "#, |
755 | expect![[r#" | 755 | expect![[r#" |
@@ -770,7 +770,7 @@ enum Foo { | |||
770 | 770 | ||
771 | impl Foo { | 771 | impl Foo { |
772 | fn foo(self) { | 772 | fn foo(self) { |
773 | Self::<|> | 773 | Self::$0 |
774 | } | 774 | } |
775 | } | 775 | } |
776 | "#, | 776 | "#, |
diff --git a/crates/completion/src/completions/record.rs b/crates/completion/src/completions/record.rs index 91bf4a8ad..bb6354ded 100644 --- a/crates/completion/src/completions/record.rs +++ b/crates/completion/src/completions/record.rs | |||
@@ -20,13 +20,17 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> | |||
20 | 20 | ||
21 | let missing_fields = ctx.sema.record_literal_missing_fields(record_lit); | 21 | let missing_fields = ctx.sema.record_literal_missing_fields(record_lit); |
22 | if impl_default_trait && !missing_fields.is_empty() { | 22 | if impl_default_trait && !missing_fields.is_empty() { |
23 | let completion_text = "..Default::default()"; | ||
24 | let completion_text = completion_text | ||
25 | .strip_prefix(ctx.token.to_string().as_str()) | ||
26 | .unwrap_or(completion_text); | ||
23 | acc.add( | 27 | acc.add( |
24 | CompletionItem::new( | 28 | CompletionItem::new( |
25 | CompletionKind::Snippet, | 29 | CompletionKind::Snippet, |
26 | ctx.source_range(), | 30 | ctx.source_range(), |
27 | "..Default::default()", | 31 | "..Default::default()", |
28 | ) | 32 | ) |
29 | .insert_text("..Default::default()") | 33 | .insert_text(completion_text) |
30 | .kind(CompletionItemKind::Field) | 34 | .kind(CompletionItemKind::Field) |
31 | .build(), | 35 | .build(), |
32 | ); | 36 | ); |
@@ -48,7 +52,10 @@ mod tests { | |||
48 | use expect_test::{expect, Expect}; | 52 | use expect_test::{expect, Expect}; |
49 | use ide_db::helpers::FamousDefs; | 53 | use ide_db::helpers::FamousDefs; |
50 | 54 | ||
51 | use crate::{test_utils::completion_list, CompletionKind}; | 55 | use crate::{ |
56 | test_utils::{self, completion_list}, | ||
57 | CompletionKind, | ||
58 | }; | ||
52 | 59 | ||
53 | fn check(ra_fixture: &str, expect: Expect) { | 60 | fn check(ra_fixture: &str, expect: Expect) { |
54 | let actual = completion_list(ra_fixture, CompletionKind::Reference); | 61 | let actual = completion_list(ra_fixture, CompletionKind::Reference); |
@@ -63,6 +70,18 @@ mod tests { | |||
63 | expect.assert_eq(&actual); | 70 | expect.assert_eq(&actual); |
64 | } | 71 | } |
65 | 72 | ||
73 | fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | ||
74 | test_utils::check_edit( | ||
75 | what, | ||
76 | &format!( | ||
77 | "//- /main.rs crate:main deps:core{}\n{}", | ||
78 | ra_fixture_before, | ||
79 | FamousDefs::FIXTURE, | ||
80 | ), | ||
81 | &(ra_fixture_after.to_owned() + "\n"), | ||
82 | ); | ||
83 | } | ||
84 | |||
66 | #[test] | 85 | #[test] |
67 | fn test_record_literal_field_default() { | 86 | fn test_record_literal_field_default() { |
68 | let test_code = r#" | 87 | let test_code = r#" |
@@ -80,7 +99,7 @@ impl core::default::Default for S { | |||
80 | fn process(f: S) { | 99 | fn process(f: S) { |
81 | let other = S { | 100 | let other = S { |
82 | foo: 5, | 101 | foo: 5, |
83 | .<|> | 102 | .$0 |
84 | }; | 103 | }; |
85 | } | 104 | } |
86 | "#; | 105 | "#; |
@@ -102,6 +121,51 @@ fn process(f: S) { | |||
102 | } | 121 | } |
103 | 122 | ||
104 | #[test] | 123 | #[test] |
124 | fn test_record_literal_field_default_completion() { | ||
125 | check_edit( | ||
126 | "..Default::default()", | ||
127 | r#" | ||
128 | struct S { foo: u32, bar: usize } | ||
129 | |||
130 | impl core::default::Default for S { | ||
131 | fn default() -> Self { | ||
132 | S { | ||
133 | foo: 0, | ||
134 | bar: 0, | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | |||
139 | fn process(f: S) { | ||
140 | let other = S { | ||
141 | foo: 5, | ||
142 | .$0 | ||
143 | }; | ||
144 | } | ||
145 | "#, | ||
146 | r#" | ||
147 | struct S { foo: u32, bar: usize } | ||
148 | |||
149 | impl core::default::Default for S { | ||
150 | fn default() -> Self { | ||
151 | S { | ||
152 | foo: 0, | ||
153 | bar: 0, | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | |||
158 | fn process(f: S) { | ||
159 | let other = S { | ||
160 | foo: 5, | ||
161 | ..Default::default() | ||
162 | }; | ||
163 | } | ||
164 | "#, | ||
165 | ); | ||
166 | } | ||
167 | |||
168 | #[test] | ||
105 | fn test_record_literal_field_without_default() { | 169 | fn test_record_literal_field_without_default() { |
106 | let test_code = r#" | 170 | let test_code = r#" |
107 | struct S { foo: u32, bar: usize } | 171 | struct S { foo: u32, bar: usize } |
@@ -109,7 +173,7 @@ struct S { foo: u32, bar: usize } | |||
109 | fn process(f: S) { | 173 | fn process(f: S) { |
110 | let other = S { | 174 | let other = S { |
111 | foo: 5, | 175 | foo: 5, |
112 | .<|> | 176 | .$0 |
113 | }; | 177 | }; |
114 | } | 178 | } |
115 | "#; | 179 | "#; |
@@ -137,7 +201,7 @@ struct S { foo: u32 } | |||
137 | 201 | ||
138 | fn process(f: S) { | 202 | fn process(f: S) { |
139 | match f { | 203 | match f { |
140 | S { f<|>: 92 } => (), | 204 | S { f$0: 92 } => (), |
141 | } | 205 | } |
142 | } | 206 | } |
143 | "#, | 207 | "#, |
@@ -155,7 +219,7 @@ enum E { S { foo: u32, bar: () } } | |||
155 | 219 | ||
156 | fn process(e: E) { | 220 | fn process(e: E) { |
157 | match e { | 221 | match e { |
158 | E::S { <|> } => (), | 222 | E::S { $0 } => (), |
159 | } | 223 | } |
160 | } | 224 | } |
161 | "#, | 225 | "#, |
@@ -175,7 +239,7 @@ struct S { foo: u32 } | |||
175 | 239 | ||
176 | fn process(f: S) { | 240 | fn process(f: S) { |
177 | m!(match f { | 241 | m!(match f { |
178 | S { f<|>: 92 } => (), | 242 | S { f$0: 92 } => (), |
179 | }) | 243 | }) |
180 | } | 244 | } |
181 | ", | 245 | ", |
@@ -199,7 +263,7 @@ fn main() { | |||
199 | foo1: 1, foo2: 2, | 263 | foo1: 1, foo2: 2, |
200 | bar: 3, baz: 4, | 264 | bar: 3, baz: 4, |
201 | }; | 265 | }; |
202 | if let S { foo1, foo2: a, <|> } = s {} | 266 | if let S { foo1, foo2: a, $0 } = s {} |
203 | } | 267 | } |
204 | "#, | 268 | "#, |
205 | expect![[r#" | 269 | expect![[r#" |
@@ -215,7 +279,7 @@ fn main() { | |||
215 | r#" | 279 | r#" |
216 | struct A { the_field: u32 } | 280 | struct A { the_field: u32 } |
217 | fn foo() { | 281 | fn foo() { |
218 | A { the<|> } | 282 | A { the$0 } |
219 | } | 283 | } |
220 | "#, | 284 | "#, |
221 | expect![[r#" | 285 | expect![[r#" |
@@ -230,7 +294,7 @@ fn foo() { | |||
230 | r#" | 294 | r#" |
231 | enum E { A { a: u32 } } | 295 | enum E { A { a: u32 } } |
232 | fn foo() { | 296 | fn foo() { |
233 | let _ = E::A { <|> } | 297 | let _ = E::A { $0 } |
234 | } | 298 | } |
235 | "#, | 299 | "#, |
236 | expect![[r#" | 300 | expect![[r#" |
@@ -247,7 +311,7 @@ struct A { a: u32 } | |||
247 | struct B { b: u32 } | 311 | struct B { b: u32 } |
248 | 312 | ||
249 | fn foo() { | 313 | fn foo() { |
250 | let _: A = B { <|> } | 314 | let _: A = B { $0 } |
251 | } | 315 | } |
252 | "#, | 316 | "#, |
253 | expect![[r#" | 317 | expect![[r#" |
@@ -263,7 +327,7 @@ fn foo() { | |||
263 | struct A<T> { a: T } | 327 | struct A<T> { a: T } |
264 | 328 | ||
265 | fn foo() { | 329 | fn foo() { |
266 | let _: A<u32> = A { <|> } | 330 | let _: A<u32> = A { $0 } |
267 | } | 331 | } |
268 | "#, | 332 | "#, |
269 | expect![[r#" | 333 | expect![[r#" |
@@ -279,7 +343,7 @@ fn foo() { | |||
279 | macro_rules! m { ($e:expr) => { $e } } | 343 | macro_rules! m { ($e:expr) => { $e } } |
280 | struct A { the_field: u32 } | 344 | struct A { the_field: u32 } |
281 | fn foo() { | 345 | fn foo() { |
282 | m!(A { the<|> }) | 346 | m!(A { the$0 }) |
283 | } | 347 | } |
284 | "#, | 348 | "#, |
285 | expect![[r#" | 349 | expect![[r#" |
@@ -299,7 +363,7 @@ struct S { | |||
299 | 363 | ||
300 | fn main() { | 364 | fn main() { |
301 | let foo1 = 1; | 365 | let foo1 = 1; |
302 | let s = S { foo1, foo2: 5, <|> } | 366 | let s = S { foo1, foo2: 5, $0 } |
303 | } | 367 | } |
304 | "#, | 368 | "#, |
305 | expect![[r#" | 369 | expect![[r#" |
@@ -317,7 +381,7 @@ struct S { foo1: u32, foo2: u32 } | |||
317 | 381 | ||
318 | fn main() { | 382 | fn main() { |
319 | let foo1 = 1; | 383 | let foo1 = 1; |
320 | let s = S { foo1, <|> .. loop {} } | 384 | let s = S { foo1, $0 .. loop {} } |
321 | } | 385 | } |
322 | "#, | 386 | "#, |
323 | expect![[r#" | 387 | expect![[r#" |
diff --git a/crates/completion/src/completions/snippet.rs b/crates/completion/src/completions/snippet.rs index 842590130..df17a15c5 100644 --- a/crates/completion/src/completions/snippet.rs +++ b/crates/completion/src/completions/snippet.rs | |||
@@ -1,8 +1,10 @@ | |||
1 | //! This file provides snippet completions, like `pd` => `eprintln!(...)`. | 1 | //! This file provides snippet completions, like `pd` => `eprintln!(...)`. |
2 | 2 | ||
3 | use ide_db::helpers::SnippetCap; | ||
4 | |||
3 | use crate::{ | 5 | use crate::{ |
4 | config::SnippetCap, item::Builder, CompletionContext, CompletionItem, CompletionItemKind, | 6 | item::Builder, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, |
5 | CompletionKind, Completions, | 7 | Completions, |
6 | }; | 8 | }; |
7 | 9 | ||
8 | fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder { | 10 | fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder { |
@@ -81,7 +83,7 @@ mod tests { | |||
81 | #[test] | 83 | #[test] |
82 | fn completes_snippets_in_expressions() { | 84 | fn completes_snippets_in_expressions() { |
83 | check( | 85 | check( |
84 | r#"fn foo(x: i32) { <|> }"#, | 86 | r#"fn foo(x: i32) { $0 }"#, |
85 | expect![[r#" | 87 | expect![[r#" |
86 | sn pd | 88 | sn pd |
87 | sn ppd | 89 | sn ppd |
@@ -91,8 +93,8 @@ mod tests { | |||
91 | 93 | ||
92 | #[test] | 94 | #[test] |
93 | fn should_not_complete_snippets_in_path() { | 95 | fn should_not_complete_snippets_in_path() { |
94 | check(r#"fn foo(x: i32) { ::foo<|> }"#, expect![[""]]); | 96 | check(r#"fn foo(x: i32) { ::foo$0 }"#, expect![[""]]); |
95 | check(r#"fn foo(x: i32) { ::<|> }"#, expect![[""]]); | 97 | check(r#"fn foo(x: i32) { ::$0 }"#, expect![[""]]); |
96 | } | 98 | } |
97 | 99 | ||
98 | #[test] | 100 | #[test] |
@@ -101,7 +103,7 @@ mod tests { | |||
101 | r#" | 103 | r#" |
102 | #[cfg(test)] | 104 | #[cfg(test)] |
103 | mod tests { | 105 | mod tests { |
104 | <|> | 106 | $0 |
105 | } | 107 | } |
106 | "#, | 108 | "#, |
107 | expect![[r#" | 109 | expect![[r#" |
diff --git a/crates/completion/src/completions/trait_impl.rs b/crates/completion/src/completions/trait_impl.rs index c4e0d0669..135ae49dc 100644 --- a/crates/completion/src/completions/trait_impl.rs +++ b/crates/completion/src/completions/trait_impl.rs | |||
@@ -15,7 +15,7 @@ | |||
15 | //! } | 15 | //! } |
16 | //! | 16 | //! |
17 | //! impl SomeTrait for () { | 17 | //! impl SomeTrait for () { |
18 | //! fn f<|> | 18 | //! fn f$0 |
19 | //! } | 19 | //! } |
20 | //! ``` | 20 | //! ``` |
21 | //! | 21 | //! |
@@ -27,7 +27,7 @@ | |||
27 | //! # } | 27 | //! # } |
28 | //! | 28 | //! |
29 | //! impl SomeTrait for () { | 29 | //! impl SomeTrait for () { |
30 | //! fn foo() {}<|> | 30 | //! fn foo() {}$0 |
31 | //! } | 31 | //! } |
32 | //! ``` | 32 | //! ``` |
33 | 33 | ||
@@ -82,7 +82,7 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext | |||
82 | 82 | ||
83 | fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> { | 83 | fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> { |
84 | let mut token = ctx.token.clone(); | 84 | let mut token = ctx.token.clone(); |
85 | // For keywork without name like `impl .. { fn <|> }`, the current position is inside | 85 | // For keywork without name like `impl .. { fn $0 }`, the current position is inside |
86 | // the whitespace token, which is outside `FN` syntax node. | 86 | // the whitespace token, which is outside `FN` syntax node. |
87 | // We need to follow the previous token in this case. | 87 | // We need to follow the previous token in this case. |
88 | if token.kind() == SyntaxKind::WHITESPACE { | 88 | if token.kind() == SyntaxKind::WHITESPACE { |
@@ -90,20 +90,20 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt | |||
90 | } | 90 | } |
91 | 91 | ||
92 | let impl_item_offset = match token.kind() { | 92 | let impl_item_offset = match token.kind() { |
93 | // `impl .. { const <|> }` | 93 | // `impl .. { const $0 }` |
94 | // ERROR 0 | 94 | // ERROR 0 |
95 | // CONST_KW <- * | 95 | // CONST_KW <- * |
96 | SyntaxKind::CONST_KW => 0, | 96 | T![const] => 0, |
97 | // `impl .. { fn/type <|> }` | 97 | // `impl .. { fn/type $0 }` |
98 | // FN/TYPE_ALIAS 0 | 98 | // FN/TYPE_ALIAS 0 |
99 | // FN_KW <- * | 99 | // FN_KW <- * |
100 | SyntaxKind::FN_KW | SyntaxKind::TYPE_KW => 0, | 100 | T![fn] | T![type] => 0, |
101 | // `impl .. { fn/type/const foo<|> }` | 101 | // `impl .. { fn/type/const foo$0 }` |
102 | // FN/TYPE_ALIAS/CONST 1 | 102 | // FN/TYPE_ALIAS/CONST 1 |
103 | // NAME 0 | 103 | // NAME 0 |
104 | // IDENT <- * | 104 | // IDENT <- * |
105 | SyntaxKind::IDENT if token.parent().kind() == SyntaxKind::NAME => 1, | 105 | SyntaxKind::IDENT if token.parent().kind() == SyntaxKind::NAME => 1, |
106 | // `impl .. { foo<|> }` | 106 | // `impl .. { foo$0 }` |
107 | // MACRO_CALL 3 | 107 | // MACRO_CALL 3 |
108 | // PATH 2 | 108 | // PATH 2 |
109 | // PATH_SEGMENT 1 | 109 | // PATH_SEGMENT 1 |
@@ -120,8 +120,8 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt | |||
120 | // <item> | 120 | // <item> |
121 | let impl_def = ast::Impl::cast(impl_item.parent()?.parent()?)?; | 121 | let impl_def = ast::Impl::cast(impl_item.parent()?.parent()?)?; |
122 | let kind = match impl_item.kind() { | 122 | let kind = match impl_item.kind() { |
123 | // `impl ... { const <|> fn/type/const }` | 123 | // `impl ... { const $0 fn/type/const }` |
124 | _ if token.kind() == SyntaxKind::CONST_KW => ImplCompletionKind::Const, | 124 | _ if token.kind() == T![const] => ImplCompletionKind::Const, |
125 | SyntaxKind::CONST | SyntaxKind::ERROR => ImplCompletionKind::Const, | 125 | SyntaxKind::CONST | SyntaxKind::ERROR => ImplCompletionKind::Const, |
126 | SyntaxKind::TYPE_ALIAS => ImplCompletionKind::TypeAlias, | 126 | SyntaxKind::TYPE_ALIAS => ImplCompletionKind::TypeAlias, |
127 | SyntaxKind::FN => ImplCompletionKind::Fn, | 127 | SyntaxKind::FN => ImplCompletionKind::Fn, |
@@ -156,19 +156,21 @@ fn add_function_impl( | |||
156 | }; | 156 | }; |
157 | let range = TextRange::new(fn_def_node.text_range().start(), ctx.source_range().end()); | 157 | let range = TextRange::new(fn_def_node.text_range().start(), ctx.source_range().end()); |
158 | 158 | ||
159 | let function_decl = function_declaration(&func.source(ctx.db).value); | 159 | if let Some(src) = func.source(ctx.db) { |
160 | match ctx.config.snippet_cap { | 160 | let function_decl = function_declaration(&src.value); |
161 | Some(cap) => { | 161 | match ctx.config.snippet_cap { |
162 | let snippet = format!("{} {{\n $0\n}}", function_decl); | 162 | Some(cap) => { |
163 | builder.snippet_edit(cap, TextEdit::replace(range, snippet)) | 163 | let snippet = format!("{} {{\n $0\n}}", function_decl); |
164 | } | 164 | builder.snippet_edit(cap, TextEdit::replace(range, snippet)) |
165 | None => { | 165 | } |
166 | let header = format!("{} {{", function_decl); | 166 | None => { |
167 | builder.text_edit(TextEdit::replace(range, header)) | 167 | let header = format!("{} {{", function_decl); |
168 | builder.text_edit(TextEdit::replace(range, header)) | ||
169 | } | ||
168 | } | 170 | } |
171 | .kind(completion_kind) | ||
172 | .add_to(acc); | ||
169 | } | 173 | } |
170 | .kind(completion_kind) | ||
171 | .add_to(acc); | ||
172 | } | 174 | } |
173 | 175 | ||
174 | fn add_type_alias_impl( | 176 | fn add_type_alias_impl( |
@@ -200,16 +202,19 @@ fn add_const_impl( | |||
200 | let const_name = const_.name(ctx.db).map(|n| n.to_string()); | 202 | let const_name = const_.name(ctx.db).map(|n| n.to_string()); |
201 | 203 | ||
202 | if let Some(const_name) = const_name { | 204 | if let Some(const_name) = const_name { |
203 | let snippet = make_const_compl_syntax(&const_.source(ctx.db).value); | 205 | if let Some(source) = const_.source(ctx.db) { |
204 | 206 | let snippet = make_const_compl_syntax(&source.value); | |
205 | let range = TextRange::new(const_def_node.text_range().start(), ctx.source_range().end()); | 207 | |
206 | 208 | let range = | |
207 | CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone()) | 209 | TextRange::new(const_def_node.text_range().start(), ctx.source_range().end()); |
208 | .text_edit(TextEdit::replace(range, snippet)) | 210 | |
209 | .lookup_by(const_name) | 211 | CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone()) |
210 | .kind(CompletionItemKind::Const) | 212 | .text_edit(TextEdit::replace(range, snippet)) |
211 | .set_documentation(const_.docs(ctx.db)) | 213 | .lookup_by(const_name) |
212 | .add_to(acc); | 214 | .kind(CompletionItemKind::Const) |
215 | .set_documentation(const_.docs(ctx.db)) | ||
216 | .add_to(acc); | ||
217 | } | ||
213 | } | 218 | } |
214 | } | 219 | } |
215 | 220 | ||
@@ -262,7 +267,7 @@ trait Test { | |||
262 | struct T; | 267 | struct T; |
263 | 268 | ||
264 | impl Test for T { | 269 | impl Test for T { |
265 | t<|> | 270 | t$0 |
266 | } | 271 | } |
267 | "#, | 272 | "#, |
268 | expect![[" | 273 | expect![[" |
@@ -282,7 +287,7 @@ struct T; | |||
282 | 287 | ||
283 | impl Test for T { | 288 | impl Test for T { |
284 | fn test() { | 289 | fn test() { |
285 | t<|> | 290 | t$0 |
286 | } | 291 | } |
287 | } | 292 | } |
288 | ", | 293 | ", |
@@ -296,7 +301,7 @@ struct T; | |||
296 | 301 | ||
297 | impl Test for T { | 302 | impl Test for T { |
298 | fn test() { | 303 | fn test() { |
299 | fn t<|> | 304 | fn t$0 |
300 | } | 305 | } |
301 | } | 306 | } |
302 | ", | 307 | ", |
@@ -310,7 +315,7 @@ struct T; | |||
310 | 315 | ||
311 | impl Test for T { | 316 | impl Test for T { |
312 | fn test() { | 317 | fn test() { |
313 | fn <|> | 318 | fn $0 |
314 | } | 319 | } |
315 | } | 320 | } |
316 | ", | 321 | ", |
@@ -325,7 +330,7 @@ struct T; | |||
325 | 330 | ||
326 | impl Test for T { | 331 | impl Test for T { |
327 | fn test() { | 332 | fn test() { |
328 | foo.<|> | 333 | foo.$0 |
329 | } | 334 | } |
330 | } | 335 | } |
331 | ", | 336 | ", |
@@ -338,7 +343,7 @@ trait Test { fn test(_: i32); fn test2(); } | |||
338 | struct T; | 343 | struct T; |
339 | 344 | ||
340 | impl Test for T { | 345 | impl Test for T { |
341 | fn test(t<|>) | 346 | fn test(t$0) |
342 | } | 347 | } |
343 | ", | 348 | ", |
344 | expect![[""]], | 349 | expect![[""]], |
@@ -350,7 +355,7 @@ trait Test { fn test(_: fn()); fn test2(); } | |||
350 | struct T; | 355 | struct T; |
351 | 356 | ||
352 | impl Test for T { | 357 | impl Test for T { |
353 | fn test(f: fn <|>) | 358 | fn test(f: fn $0) |
354 | } | 359 | } |
355 | ", | 360 | ", |
356 | expect![[""]], | 361 | expect![[""]], |
@@ -365,7 +370,7 @@ trait Test { const TEST: fn(); const TEST2: u32; type Test; fn test(); } | |||
365 | struct T; | 370 | struct T; |
366 | 371 | ||
367 | impl Test for T { | 372 | impl Test for T { |
368 | const TEST: fn <|> | 373 | const TEST: fn $0 |
369 | } | 374 | } |
370 | ", | 375 | ", |
371 | expect![[""]], | 376 | expect![[""]], |
@@ -377,7 +382,7 @@ trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); } | |||
377 | struct T; | 382 | struct T; |
378 | 383 | ||
379 | impl Test for T { | 384 | impl Test for T { |
380 | const TEST: T<|> | 385 | const TEST: T$0 |
381 | } | 386 | } |
382 | ", | 387 | ", |
383 | expect![[""]], | 388 | expect![[""]], |
@@ -389,7 +394,7 @@ trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); } | |||
389 | struct T; | 394 | struct T; |
390 | 395 | ||
391 | impl Test for T { | 396 | impl Test for T { |
392 | const TEST: u32 = f<|> | 397 | const TEST: u32 = f$0 |
393 | } | 398 | } |
394 | ", | 399 | ", |
395 | expect![[""]], | 400 | expect![[""]], |
@@ -402,7 +407,7 @@ struct T; | |||
402 | 407 | ||
403 | impl Test for T { | 408 | impl Test for T { |
404 | const TEST: u32 = { | 409 | const TEST: u32 = { |
405 | t<|> | 410 | t$0 |
406 | }; | 411 | }; |
407 | } | 412 | } |
408 | ", | 413 | ", |
@@ -416,7 +421,7 @@ struct T; | |||
416 | 421 | ||
417 | impl Test for T { | 422 | impl Test for T { |
418 | const TEST: u32 = { | 423 | const TEST: u32 = { |
419 | fn <|> | 424 | fn $0 |
420 | }; | 425 | }; |
421 | } | 426 | } |
422 | ", | 427 | ", |
@@ -430,7 +435,7 @@ struct T; | |||
430 | 435 | ||
431 | impl Test for T { | 436 | impl Test for T { |
432 | const TEST: u32 = { | 437 | const TEST: u32 = { |
433 | fn t<|> | 438 | fn t$0 |
434 | }; | 439 | }; |
435 | } | 440 | } |
436 | ", | 441 | ", |
@@ -446,7 +451,7 @@ trait Test { type Test; type Test2; fn test(); } | |||
446 | struct T; | 451 | struct T; |
447 | 452 | ||
448 | impl Test for T { | 453 | impl Test for T { |
449 | type Test = T<|>; | 454 | type Test = T$0; |
450 | } | 455 | } |
451 | ", | 456 | ", |
452 | expect![[""]], | 457 | expect![[""]], |
@@ -458,7 +463,7 @@ trait Test { type Test; type Test2; fn test(); } | |||
458 | struct T; | 463 | struct T; |
459 | 464 | ||
460 | impl Test for T { | 465 | impl Test for T { |
461 | type Test = fn <|>; | 466 | type Test = fn $0; |
462 | } | 467 | } |
463 | ", | 468 | ", |
464 | expect![[""]], | 469 | expect![[""]], |
@@ -476,7 +481,7 @@ trait Test { | |||
476 | struct T; | 481 | struct T; |
477 | 482 | ||
478 | impl Test for T { | 483 | impl Test for T { |
479 | t<|> | 484 | t$0 |
480 | } | 485 | } |
481 | "#, | 486 | "#, |
482 | r#" | 487 | r#" |
@@ -505,7 +510,7 @@ trait Test { | |||
505 | struct T; | 510 | struct T; |
506 | 511 | ||
507 | impl Test for T { | 512 | impl Test for T { |
508 | fn t<|> | 513 | fn t$0 |
509 | } | 514 | } |
510 | "#, | 515 | "#, |
511 | r#" | 516 | r#" |
@@ -535,7 +540,7 @@ struct T; | |||
535 | 540 | ||
536 | impl Test for T { | 541 | impl Test for T { |
537 | fn foo() {} | 542 | fn foo() {} |
538 | fn f<|> | 543 | fn f$0 |
539 | } | 544 | } |
540 | "#, | 545 | "#, |
541 | expect![[r#" | 546 | expect![[r#" |
@@ -555,7 +560,7 @@ trait Test { | |||
555 | struct T; | 560 | struct T; |
556 | 561 | ||
557 | impl Test for T { | 562 | impl Test for T { |
558 | fn f<|> | 563 | fn f$0 |
559 | } | 564 | } |
560 | "#, | 565 | "#, |
561 | r#" | 566 | r#" |
@@ -580,7 +585,7 @@ trait Test { | |||
580 | struct T; | 585 | struct T; |
581 | 586 | ||
582 | impl Test for T { | 587 | impl Test for T { |
583 | fn f<|> | 588 | fn f$0 |
584 | } | 589 | } |
585 | "#, | 590 | "#, |
586 | r#" | 591 | r#" |
@@ -609,7 +614,7 @@ trait Test { | |||
609 | } | 614 | } |
610 | 615 | ||
611 | impl Test for () { | 616 | impl Test for () { |
612 | type S<|> | 617 | type S$0 |
613 | } | 618 | } |
614 | "#, | 619 | "#, |
615 | " | 620 | " |
@@ -634,7 +639,7 @@ trait Test { | |||
634 | } | 639 | } |
635 | 640 | ||
636 | impl Test for () { | 641 | impl Test for () { |
637 | const S<|> | 642 | const S$0 |
638 | } | 643 | } |
639 | "#, | 644 | "#, |
640 | " | 645 | " |
@@ -656,7 +661,7 @@ trait Test { | |||
656 | } | 661 | } |
657 | 662 | ||
658 | impl Test for () { | 663 | impl Test for () { |
659 | const S<|> | 664 | const S$0 |
660 | } | 665 | } |
661 | "#, | 666 | "#, |
662 | " | 667 | " |
@@ -719,7 +724,7 @@ impl Test for T {{ | |||
719 | // Enumerate some possible next siblings. | 724 | // Enumerate some possible next siblings. |
720 | for next_sibling in &[ | 725 | for next_sibling in &[ |
721 | "", | 726 | "", |
722 | "fn other_fn() {}", // `const <|> fn` -> `const fn` | 727 | "fn other_fn() {}", // `const $0 fn` -> `const fn` |
723 | "type OtherType = i32;", | 728 | "type OtherType = i32;", |
724 | "const OTHER_CONST: i32 = 0;", | 729 | "const OTHER_CONST: i32 = 0;", |
725 | "async fn other_fn() {}", | 730 | "async fn other_fn() {}", |
@@ -728,9 +733,9 @@ impl Test for T {{ | |||
728 | "default type OtherType = i32;", | 733 | "default type OtherType = i32;", |
729 | "default const OTHER_CONST: i32 = 0;", | 734 | "default const OTHER_CONST: i32 = 0;", |
730 | ] { | 735 | ] { |
731 | test("bar", "fn <|>", "fn bar() {\n $0\n}", next_sibling); | 736 | test("bar", "fn $0", "fn bar() {\n $0\n}", next_sibling); |
732 | test("Foo", "type <|>", "type Foo = ", next_sibling); | 737 | test("Foo", "type $0", "type Foo = ", next_sibling); |
733 | test("CONST", "const <|>", "const CONST: u16 = ", next_sibling); | 738 | test("CONST", "const $0", "const CONST: u16 = ", next_sibling); |
734 | } | 739 | } |
735 | } | 740 | } |
736 | } | 741 | } |
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs index 81a6d00e2..12cdb869d 100644 --- a/crates/completion/src/completions/unqualified_path.rs +++ b/crates/completion/src/completions/unqualified_path.rs | |||
@@ -46,7 +46,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC | |||
46 | acc.add_resolution(ctx, name.to_string(), &res) | 46 | acc.add_resolution(ctx, name.to_string(), &res) |
47 | }); | 47 | }); |
48 | 48 | ||
49 | if ctx.config.enable_autoimport_completions && ctx.config.resolve_additional_edits_lazily() { | 49 | if ctx.config.enable_autoimport_completions { |
50 | fuzzy_completion(acc, ctx); | 50 | fuzzy_completion(acc, ctx); |
51 | } | 51 | } |
52 | } | 52 | } |
@@ -85,7 +85,7 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T | |||
85 | // | 85 | // |
86 | // ``` | 86 | // ``` |
87 | // fn main() { | 87 | // fn main() { |
88 | // pda<|> | 88 | // pda$0 |
89 | // } | 89 | // } |
90 | // # pub mod std { pub mod marker { pub struct PhantomData { } } } | 90 | // # pub mod std { pub mod marker { pub struct PhantomData { } } } |
91 | // ``` | 91 | // ``` |
@@ -124,8 +124,8 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T | |||
124 | // Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding | 124 | // Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding |
125 | // capability enabled. | 125 | // capability enabled. |
126 | fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { | 126 | fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { |
127 | let _p = profile::span("fuzzy_completion"); | ||
128 | let potential_import_name = ctx.token.to_string(); | 127 | let potential_import_name = ctx.token.to_string(); |
128 | let _p = profile::span("fuzzy_completion").detail(|| potential_import_name.clone()); | ||
129 | 129 | ||
130 | if potential_import_name.len() < 2 { | 130 | if potential_import_name.len() < 2 { |
131 | return None; | 131 | return None; |
@@ -142,6 +142,7 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<() | |||
142 | Some(40), | 142 | Some(40), |
143 | potential_import_name, | 143 | potential_import_name, |
144 | true, | 144 | true, |
145 | true, | ||
145 | ) | 146 | ) |
146 | .filter_map(|import_candidate| { | 147 | .filter_map(|import_candidate| { |
147 | Some(match import_candidate { | 148 | Some(match import_candidate { |
@@ -191,12 +192,14 @@ mod tests { | |||
191 | use test_utils::mark; | 192 | use test_utils::mark; |
192 | 193 | ||
193 | use crate::{ | 194 | use crate::{ |
194 | test_utils::{check_edit, check_edit_with_config, completion_list_with_config}, | 195 | test_utils::{ |
196 | check_edit, check_edit_with_config, completion_list_with_config, TEST_CONFIG, | ||
197 | }, | ||
195 | CompletionConfig, CompletionKind, | 198 | CompletionConfig, CompletionKind, |
196 | }; | 199 | }; |
197 | 200 | ||
198 | fn check(ra_fixture: &str, expect: Expect) { | 201 | fn check(ra_fixture: &str, expect: Expect) { |
199 | check_with_config(CompletionConfig::default(), ra_fixture, expect); | 202 | check_with_config(TEST_CONFIG, ra_fixture, expect); |
200 | } | 203 | } |
201 | 204 | ||
202 | fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) { | 205 | fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) { |
@@ -204,20 +207,12 @@ mod tests { | |||
204 | expect.assert_eq(&actual) | 207 | expect.assert_eq(&actual) |
205 | } | 208 | } |
206 | 209 | ||
207 | fn fuzzy_completion_config() -> CompletionConfig { | ||
208 | let mut completion_config = CompletionConfig::default(); | ||
209 | completion_config | ||
210 | .active_resolve_capabilities | ||
211 | .insert(crate::CompletionResolveCapability::AdditionalTextEdits); | ||
212 | completion_config | ||
213 | } | ||
214 | |||
215 | #[test] | 210 | #[test] |
216 | fn self_fulfilling_completion() { | 211 | fn self_fulfilling_completion() { |
217 | mark::check!(self_fulfilling_completion); | 212 | mark::check!(self_fulfilling_completion); |
218 | check( | 213 | check( |
219 | r#" | 214 | r#" |
220 | use foo<|> | 215 | use foo$0 |
221 | use std::collections; | 216 | use std::collections; |
222 | "#, | 217 | "#, |
223 | expect![[r#" | 218 | expect![[r#" |
@@ -234,7 +229,7 @@ enum Enum { A, B } | |||
234 | fn quux(x: Option<Enum>) { | 229 | fn quux(x: Option<Enum>) { |
235 | match x { | 230 | match x { |
236 | None => (), | 231 | None => (), |
237 | Some(en<|> @ Enum::A) => (), | 232 | Some(en$0 @ Enum::A) => (), |
238 | } | 233 | } |
239 | } | 234 | } |
240 | "#, | 235 | "#, |
@@ -250,7 +245,7 @@ enum Enum { A, B } | |||
250 | fn quux(x: Option<Enum>) { | 245 | fn quux(x: Option<Enum>) { |
251 | match x { | 246 | match x { |
252 | None => (), | 247 | None => (), |
253 | Some(ref en<|>) => (), | 248 | Some(ref en$0) => (), |
254 | } | 249 | } |
255 | } | 250 | } |
256 | "#, | 251 | "#, |
@@ -266,7 +261,7 @@ enum Enum { A, B } | |||
266 | fn quux(x: Option<Enum>) { | 261 | fn quux(x: Option<Enum>) { |
267 | match x { | 262 | match x { |
268 | None => (), | 263 | None => (), |
269 | Some(En<|>) => (), | 264 | Some(En$0) => (), |
270 | } | 265 | } |
271 | } | 266 | } |
272 | "#, | 267 | "#, |
@@ -282,7 +277,7 @@ fn quux(x: Option<Enum>) { | |||
282 | r#" | 277 | r#" |
283 | fn quux(x: i32) { | 278 | fn quux(x: i32) { |
284 | let y = 92; | 279 | let y = 92; |
285 | 1 + <|>; | 280 | 1 + $0; |
286 | let z = (); | 281 | let z = (); |
287 | } | 282 | } |
288 | "#, | 283 | "#, |
@@ -304,7 +299,7 @@ fn quux() { | |||
304 | }; | 299 | }; |
305 | if let Some(a) = bar() { | 300 | if let Some(a) = bar() { |
306 | let b = 62; | 301 | let b = 62; |
307 | 1 + <|> | 302 | 1 + $0 |
308 | } | 303 | } |
309 | } | 304 | } |
310 | "#, | 305 | "#, |
@@ -321,7 +316,7 @@ fn quux() { | |||
321 | check( | 316 | check( |
322 | r#" | 317 | r#" |
323 | fn quux() { | 318 | fn quux() { |
324 | for x in &[1, 2, 3] { <|> } | 319 | for x in &[1, 2, 3] { $0 } |
325 | } | 320 | } |
326 | "#, | 321 | "#, |
327 | expect![[r#" | 322 | expect![[r#" |
@@ -339,7 +334,7 @@ fn quux() { | |||
339 | r#" | 334 | r#" |
340 | fn main() { | 335 | fn main() { |
341 | let wherewolf = 92; | 336 | let wherewolf = 92; |
342 | drop(where<|>) | 337 | drop(where$0) |
343 | } | 338 | } |
344 | "#, | 339 | "#, |
345 | r#" | 340 | r#" |
@@ -354,7 +349,7 @@ fn main() { | |||
354 | #[test] | 349 | #[test] |
355 | fn completes_generic_params() { | 350 | fn completes_generic_params() { |
356 | check( | 351 | check( |
357 | r#"fn quux<T>() { <|> }"#, | 352 | r#"fn quux<T>() { $0 }"#, |
358 | expect![[r#" | 353 | expect![[r#" |
359 | tp T | 354 | tp T |
360 | fn quux() fn quux<T>() | 355 | fn quux() fn quux<T>() |
@@ -365,7 +360,7 @@ fn main() { | |||
365 | #[test] | 360 | #[test] |
366 | fn completes_generic_params_in_struct() { | 361 | fn completes_generic_params_in_struct() { |
367 | check( | 362 | check( |
368 | r#"struct S<T> { x: <|>}"#, | 363 | r#"struct S<T> { x: $0}"#, |
369 | expect![[r#" | 364 | expect![[r#" |
370 | tp Self | 365 | tp Self |
371 | tp T | 366 | tp T |
@@ -377,7 +372,7 @@ fn main() { | |||
377 | #[test] | 372 | #[test] |
378 | fn completes_self_in_enum() { | 373 | fn completes_self_in_enum() { |
379 | check( | 374 | check( |
380 | r#"enum X { Y(<|>) }"#, | 375 | r#"enum X { Y($0) }"#, |
381 | expect![[r#" | 376 | expect![[r#" |
382 | tp Self | 377 | tp Self |
383 | en X | 378 | en X |
@@ -391,7 +386,7 @@ fn main() { | |||
391 | r#" | 386 | r#" |
392 | struct S; | 387 | struct S; |
393 | enum E {} | 388 | enum E {} |
394 | fn quux() { <|> } | 389 | fn quux() { $0 } |
395 | "#, | 390 | "#, |
396 | expect![[r#" | 391 | expect![[r#" |
397 | st S | 392 | st S |
@@ -408,7 +403,7 @@ fn quux() { <|> } | |||
408 | "_alpha", | 403 | "_alpha", |
409 | r#" | 404 | r#" |
410 | fn main() { | 405 | fn main() { |
411 | _<|> | 406 | _$0 |
412 | } | 407 | } |
413 | fn _alpha() {} | 408 | fn _alpha() {} |
414 | "#, | 409 | "#, |
@@ -426,7 +421,7 @@ fn _alpha() {} | |||
426 | check( | 421 | check( |
427 | r#" | 422 | r#" |
428 | //- /lib.rs crate:main deps:other_crate | 423 | //- /lib.rs crate:main deps:other_crate |
429 | use <|>; | 424 | use $0; |
430 | 425 | ||
431 | //- /other_crate/lib.rs crate:other_crate | 426 | //- /other_crate/lib.rs crate:other_crate |
432 | // nothing here | 427 | // nothing here |
@@ -444,7 +439,7 @@ use <|>; | |||
444 | struct Foo; | 439 | struct Foo; |
445 | mod m { | 440 | mod m { |
446 | struct Bar; | 441 | struct Bar; |
447 | fn quux() { <|> } | 442 | fn quux() { $0 } |
448 | } | 443 | } |
449 | "#, | 444 | "#, |
450 | expect![[r#" | 445 | expect![[r#" |
@@ -459,7 +454,7 @@ mod m { | |||
459 | check( | 454 | check( |
460 | r#" | 455 | r#" |
461 | struct Foo; | 456 | struct Foo; |
462 | fn x() -> <|> | 457 | fn x() -> $0 |
463 | "#, | 458 | "#, |
464 | expect![[r#" | 459 | expect![[r#" |
465 | st Foo | 460 | st Foo |
@@ -476,7 +471,7 @@ fn foo() { | |||
476 | let bar = 92; | 471 | let bar = 92; |
477 | { | 472 | { |
478 | let bar = 62; | 473 | let bar = 62; |
479 | drop(<|>) | 474 | drop($0) |
480 | } | 475 | } |
481 | } | 476 | } |
482 | "#, | 477 | "#, |
@@ -492,7 +487,7 @@ fn foo() { | |||
492 | #[test] | 487 | #[test] |
493 | fn completes_self_in_methods() { | 488 | fn completes_self_in_methods() { |
494 | check( | 489 | check( |
495 | r#"impl S { fn foo(&self) { <|> } }"#, | 490 | r#"impl S { fn foo(&self) { $0 } }"#, |
496 | expect![[r#" | 491 | expect![[r#" |
497 | bn self &{unknown} | 492 | bn self &{unknown} |
498 | tp Self | 493 | tp Self |
@@ -505,7 +500,7 @@ fn foo() { | |||
505 | check( | 500 | check( |
506 | r#" | 501 | r#" |
507 | //- /main.rs crate:main deps:std | 502 | //- /main.rs crate:main deps:std |
508 | fn foo() { let x: <|> } | 503 | fn foo() { let x: $0 } |
509 | 504 | ||
510 | //- /std/lib.rs crate:std | 505 | //- /std/lib.rs crate:std |
511 | #[prelude_import] | 506 | #[prelude_import] |
@@ -526,7 +521,7 @@ mod prelude { struct Option; } | |||
526 | check( | 521 | check( |
527 | r#" | 522 | r#" |
528 | //- /main.rs crate:main deps:core,std | 523 | //- /main.rs crate:main deps:core,std |
529 | fn foo() { let x: <|> } | 524 | fn foo() { let x: $0 } |
530 | 525 | ||
531 | //- /core/lib.rs crate:core | 526 | //- /core/lib.rs crate:core |
532 | #[prelude_import] | 527 | #[prelude_import] |
@@ -567,7 +562,7 @@ mod m2 { | |||
567 | macro_rules! baz { () => {} } | 562 | macro_rules! baz { () => {} } |
568 | } | 563 | } |
569 | 564 | ||
570 | fn main() { let v = <|> } | 565 | fn main() { let v = $0 } |
571 | "#, | 566 | "#, |
572 | expect![[r##" | 567 | expect![[r##" |
573 | md m1 | 568 | md m1 |
@@ -586,7 +581,7 @@ fn main() { let v = <|> } | |||
586 | check( | 581 | check( |
587 | r#" | 582 | r#" |
588 | macro_rules! foo { () => {} } | 583 | macro_rules! foo { () => {} } |
589 | fn foo() { <|> } | 584 | fn foo() { $0 } |
590 | "#, | 585 | "#, |
591 | expect![[r#" | 586 | expect![[r#" |
592 | fn foo() fn foo() | 587 | fn foo() fn foo() |
@@ -600,7 +595,7 @@ fn foo() { <|> } | |||
600 | check( | 595 | check( |
601 | r#" | 596 | r#" |
602 | macro_rules! foo { () => {} } | 597 | macro_rules! foo { () => {} } |
603 | fn main() { let x: <|> } | 598 | fn main() { let x: $0 } |
604 | "#, | 599 | "#, |
605 | expect![[r#" | 600 | expect![[r#" |
606 | fn main() fn main() | 601 | fn main() fn main() |
@@ -614,7 +609,7 @@ fn main() { let x: <|> } | |||
614 | check( | 609 | check( |
615 | r#" | 610 | r#" |
616 | macro_rules! foo { () => {} } | 611 | macro_rules! foo { () => {} } |
617 | fn main() { <|> } | 612 | fn main() { $0 } |
618 | "#, | 613 | "#, |
619 | expect![[r#" | 614 | expect![[r#" |
620 | fn main() fn main() | 615 | fn main() fn main() |
@@ -628,7 +623,7 @@ fn main() { <|> } | |||
628 | check( | 623 | check( |
629 | r#" | 624 | r#" |
630 | fn main() { | 625 | fn main() { |
631 | return f<|>; | 626 | return f$0; |
632 | fn frobnicate() {} | 627 | fn frobnicate() {} |
633 | } | 628 | } |
634 | "#, | 629 | "#, |
@@ -646,7 +641,7 @@ fn main() { | |||
646 | macro_rules! m { ($e:expr) => { $e } } | 641 | macro_rules! m { ($e:expr) => { $e } } |
647 | fn quux(x: i32) { | 642 | fn quux(x: i32) { |
648 | let y = 92; | 643 | let y = 92; |
649 | m!(<|>); | 644 | m!($0); |
650 | } | 645 | } |
651 | "#, | 646 | "#, |
652 | expect![[r#" | 647 | expect![[r#" |
@@ -665,7 +660,7 @@ fn quux(x: i32) { | |||
665 | macro_rules! m { ($e:expr) => { $e } } | 660 | macro_rules! m { ($e:expr) => { $e } } |
666 | fn quux(x: i32) { | 661 | fn quux(x: i32) { |
667 | let y = 92; | 662 | let y = 92; |
668 | m!(x<|>); | 663 | m!(x$0); |
669 | } | 664 | } |
670 | ", | 665 | ", |
671 | expect![[r#" | 666 | expect![[r#" |
@@ -684,7 +679,7 @@ fn quux(x: i32) { | |||
684 | macro_rules! m { ($e:expr) => { $e } } | 679 | macro_rules! m { ($e:expr) => { $e } } |
685 | fn quux(x: i32) { | 680 | fn quux(x: i32) { |
686 | let y = 92; | 681 | let y = 92; |
687 | m!(x<|> | 682 | m!(x$0 |
688 | } | 683 | } |
689 | "#, | 684 | "#, |
690 | expect![[r#" | 685 | expect![[r#" |
@@ -702,7 +697,7 @@ fn quux(x: i32) { | |||
702 | r#" | 697 | r#" |
703 | use spam::Quux; | 698 | use spam::Quux; |
704 | 699 | ||
705 | fn main() { <|> } | 700 | fn main() { $0 } |
706 | "#, | 701 | "#, |
707 | expect![[r#" | 702 | expect![[r#" |
708 | fn main() fn main() | 703 | fn main() fn main() |
@@ -719,7 +714,7 @@ enum Foo { Bar, Baz, Quux } | |||
719 | 714 | ||
720 | fn main() { | 715 | fn main() { |
721 | let foo = Foo::Quux; | 716 | let foo = Foo::Quux; |
722 | match foo { Qu<|> } | 717 | match foo { Qu$0 } |
723 | } | 718 | } |
724 | "#, | 719 | "#, |
725 | expect![[r#" | 720 | expect![[r#" |
@@ -739,7 +734,7 @@ enum Foo { Bar, Baz, Quux } | |||
739 | 734 | ||
740 | fn main() { | 735 | fn main() { |
741 | let foo = Foo::Quux; | 736 | let foo = Foo::Quux; |
742 | match &foo { Qu<|> } | 737 | match &foo { Qu$0 } |
743 | } | 738 | } |
744 | "#, | 739 | "#, |
745 | expect![[r#" | 740 | expect![[r#" |
@@ -759,7 +754,7 @@ enum Foo { Bar, Baz, Quux } | |||
759 | 754 | ||
760 | fn main() { | 755 | fn main() { |
761 | let foo = Foo::Quux; | 756 | let foo = Foo::Quux; |
762 | if let Qu<|> = foo { } | 757 | if let Qu$0 = foo { } |
763 | } | 758 | } |
764 | "#, | 759 | "#, |
765 | expect![[r#" | 760 | expect![[r#" |
@@ -776,7 +771,7 @@ fn main() { | |||
776 | check( | 771 | check( |
777 | r#" | 772 | r#" |
778 | enum Foo { Bar, Baz, Quux } | 773 | enum Foo { Bar, Baz, Quux } |
779 | fn main() { let foo: Foo = Q<|> } | 774 | fn main() { let foo: Foo = Q$0 } |
780 | "#, | 775 | "#, |
781 | expect![[r#" | 776 | expect![[r#" |
782 | ev Foo::Bar () | 777 | ev Foo::Bar () |
@@ -793,7 +788,7 @@ fn main() { let foo: Foo = Q<|> } | |||
793 | check( | 788 | check( |
794 | r#" | 789 | r#" |
795 | mod m { pub enum E { V } } | 790 | mod m { pub enum E { V } } |
796 | fn f() -> m::E { V<|> } | 791 | fn f() -> m::E { V$0 } |
797 | "#, | 792 | "#, |
798 | expect![[r#" | 793 | expect![[r#" |
799 | ev m::E::V () | 794 | ev m::E::V () |
@@ -808,7 +803,7 @@ fn f() -> m::E { V<|> } | |||
808 | check( | 803 | check( |
809 | r#" | 804 | r#" |
810 | struct Foo; | 805 | struct Foo; |
811 | #[<|>] | 806 | #[$0] |
812 | fn f() {} | 807 | fn f() {} |
813 | "#, | 808 | "#, |
814 | expect![[""]], | 809 | expect![[""]], |
@@ -822,7 +817,7 @@ fn f() {} | |||
822 | trait MyTrait {} | 817 | trait MyTrait {} |
823 | struct MyStruct {} | 818 | struct MyStruct {} |
824 | 819 | ||
825 | impl My<|> | 820 | impl My$0 |
826 | "#, | 821 | "#, |
827 | expect![[r#" | 822 | expect![[r#" |
828 | tp Self | 823 | tp Self |
@@ -835,7 +830,7 @@ impl My<|> | |||
835 | #[test] | 830 | #[test] |
836 | fn function_fuzzy_completion() { | 831 | fn function_fuzzy_completion() { |
837 | check_edit_with_config( | 832 | check_edit_with_config( |
838 | fuzzy_completion_config(), | 833 | TEST_CONFIG, |
839 | "stdin", | 834 | "stdin", |
840 | r#" | 835 | r#" |
841 | //- /lib.rs crate:dep | 836 | //- /lib.rs crate:dep |
@@ -845,7 +840,7 @@ pub mod io { | |||
845 | 840 | ||
846 | //- /main.rs crate:main deps:dep | 841 | //- /main.rs crate:main deps:dep |
847 | fn main() { | 842 | fn main() { |
848 | stdi<|> | 843 | stdi$0 |
849 | } | 844 | } |
850 | "#, | 845 | "#, |
851 | r#" | 846 | r#" |
@@ -861,7 +856,7 @@ fn main() { | |||
861 | #[test] | 856 | #[test] |
862 | fn macro_fuzzy_completion() { | 857 | fn macro_fuzzy_completion() { |
863 | check_edit_with_config( | 858 | check_edit_with_config( |
864 | fuzzy_completion_config(), | 859 | TEST_CONFIG, |
865 | "macro_with_curlies!", | 860 | "macro_with_curlies!", |
866 | r#" | 861 | r#" |
867 | //- /lib.rs crate:dep | 862 | //- /lib.rs crate:dep |
@@ -873,7 +868,7 @@ macro_rules! macro_with_curlies { | |||
873 | 868 | ||
874 | //- /main.rs crate:main deps:dep | 869 | //- /main.rs crate:main deps:dep |
875 | fn main() { | 870 | fn main() { |
876 | curli<|> | 871 | curli$0 |
877 | } | 872 | } |
878 | "#, | 873 | "#, |
879 | r#" | 874 | r#" |
@@ -889,7 +884,7 @@ fn main() { | |||
889 | #[test] | 884 | #[test] |
890 | fn struct_fuzzy_completion() { | 885 | fn struct_fuzzy_completion() { |
891 | check_edit_with_config( | 886 | check_edit_with_config( |
892 | fuzzy_completion_config(), | 887 | TEST_CONFIG, |
893 | "ThirdStruct", | 888 | "ThirdStruct", |
894 | r#" | 889 | r#" |
895 | //- /lib.rs crate:dep | 890 | //- /lib.rs crate:dep |
@@ -903,7 +898,7 @@ pub mod some_module { | |||
903 | use dep::{FirstStruct, some_module::SecondStruct}; | 898 | use dep::{FirstStruct, some_module::SecondStruct}; |
904 | 899 | ||
905 | fn main() { | 900 | fn main() { |
906 | this<|> | 901 | this$0 |
907 | } | 902 | } |
908 | "#, | 903 | "#, |
909 | r#" | 904 | r#" |
@@ -920,7 +915,7 @@ fn main() { | |||
920 | fn fuzzy_completions_come_in_specific_order() { | 915 | fn fuzzy_completions_come_in_specific_order() { |
921 | mark::check!(certain_fuzzy_order_test); | 916 | mark::check!(certain_fuzzy_order_test); |
922 | check_with_config( | 917 | check_with_config( |
923 | fuzzy_completion_config(), | 918 | TEST_CONFIG, |
924 | r#" | 919 | r#" |
925 | //- /lib.rs crate:dep | 920 | //- /lib.rs crate:dep |
926 | pub struct FirstStruct; | 921 | pub struct FirstStruct; |
@@ -941,7 +936,7 @@ pub mod some_module { | |||
941 | use dep::{FirstStruct, some_module::SecondStruct}; | 936 | use dep::{FirstStruct, some_module::SecondStruct}; |
942 | 937 | ||
943 | fn main() { | 938 | fn main() { |
944 | hir<|> | 939 | hir$0 |
945 | } | 940 | } |
946 | "#, | 941 | "#, |
947 | expect![[r#" | 942 | expect![[r#" |