aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/completions
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-12-22 18:03:51 +0000
committerGitHub <[email protected]>2020-12-22 18:03:51 +0000
commit4a2f60cb7b83e9ef95d97201d210ff6943b660eb (patch)
tree365de67418685046fdddb1445efab6552cbeb625 /crates/completion/src/completions
parent94f661c62a41674d9ee04c2f3cd030d639acc926 (diff)
parent83121efcd577124a992dc8bd304690b36bda2931 (diff)
Merge #6964
6964: Add full pattern completions for Struct and Variant patterns r=matklad a=Veykril Just gonna call it full pattern completion as pattern completion is already implemented in a sense by showing idents in pattern position. What this does is basically complete struct and variant patterns where applicable(function params, let statements and refutable pattern locations). This does not replace just completing the corresponding idents of the structs and variants, instead two completions are shown for these, a completion for the ident itself and a completion for the pattern(if the pattern make sense to be used that is). I figured in some cases one would rather type out the pattern manually if it has a lot of fields but you only care about one since this completion would cause one more work in the end since you would have to delete all the extra matched fields again. These completions are tagged as `CompletionKind::Snippet`, not sure if that is the right one here. <details> <summary>some gifs</summary> ![dx2lxgzhj3](https://user-images.githubusercontent.com/3757771/102719967-6987ef80-42f1-11eb-8ae0-8aff53777860.gif) ![EP2E7sJLkB](https://user-images.githubusercontent.com/3757771/102785777-c7264580-439e-11eb-8a64-f142e19fb65b.gif) ![JMNHHWknr9](https://user-images.githubusercontent.com/3757771/102785796-d1e0da80-439e-11eb-934b-218ada31b51c.gif) </details> Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/completion/src/completions')
-rw-r--r--crates/completion/src/completions/pattern.rs178
1 files changed, 161 insertions, 17 deletions
diff --git a/crates/completion/src/completions/pattern.rs b/crates/completion/src/completions/pattern.rs
index 4d56731ec..eee31098d 100644
--- a/crates/completion/src/completions/pattern.rs
+++ b/crates/completion/src/completions/pattern.rs
@@ -2,9 +2,9 @@
2 2
3use crate::{CompletionContext, Completions}; 3use crate::{CompletionContext, Completions};
4 4
5/// Completes constats and paths in patterns. 5/// Completes constants and paths in patterns.
6pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { 6pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
7 if !(ctx.is_pat_binding_or_const || ctx.is_irrefutable_let_pat_binding) { 7 if !(ctx.is_pat_binding_or_const || ctx.is_irrefutable_pat_binding) {
8 return; 8 return;
9 } 9 }
10 if ctx.record_pat_syntax.is_some() { 10 if ctx.record_pat_syntax.is_some() {
@@ -15,20 +15,21 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
15 // suggest variants + auto-imports 15 // suggest variants + auto-imports
16 ctx.scope.process_all_names(&mut |name, res| { 16 ctx.scope.process_all_names(&mut |name, res| {
17 let add_resolution = match &res { 17 let add_resolution = match &res {
18 hir::ScopeDef::ModuleDef(def) => { 18 hir::ScopeDef::ModuleDef(def) => match def {
19 if ctx.is_irrefutable_let_pat_binding { 19 hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => {
20 matches!(def, hir::ModuleDef::Adt(hir::Adt::Struct(_))) 20 acc.add_struct_pat(ctx, strukt.clone(), Some(name.clone()));
21 } else { 21 true
22 matches!(
23 def,
24 hir::ModuleDef::Adt(hir::Adt::Enum(..))
25 | hir::ModuleDef::Adt(hir::Adt::Struct(..))
26 | hir::ModuleDef::Variant(..)
27 | hir::ModuleDef::Const(..)
28 | hir::ModuleDef::Module(..)
29 )
30 } 22 }
31 } 23 hir::ModuleDef::Variant(variant) if !ctx.is_irrefutable_pat_binding => {
24 acc.add_variant_pat(ctx, variant.clone(), Some(name.clone()));
25 true
26 }
27 hir::ModuleDef::Adt(hir::Adt::Enum(..))
28 | hir::ModuleDef::Variant(..)
29 | hir::ModuleDef::Const(..)
30 | hir::ModuleDef::Module(..) => !ctx.is_irrefutable_pat_binding,
31 _ => false,
32 },
32 hir::ScopeDef::MacroDef(_) => true, 33 hir::ScopeDef::MacroDef(_) => true,
33 _ => false, 34 _ => false,
34 }; 35 };
@@ -42,13 +43,21 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
42mod tests { 43mod tests {
43 use expect_test::{expect, Expect}; 44 use expect_test::{expect, Expect};
44 45
45 use crate::{test_utils::completion_list, CompletionKind}; 46 use crate::{
47 test_utils::{check_edit, completion_list},
48 CompletionKind,
49 };
46 50
47 fn check(ra_fixture: &str, expect: Expect) { 51 fn check(ra_fixture: &str, expect: Expect) {
48 let actual = completion_list(ra_fixture, CompletionKind::Reference); 52 let actual = completion_list(ra_fixture, CompletionKind::Reference);
49 expect.assert_eq(&actual) 53 expect.assert_eq(&actual)
50 } 54 }
51 55
56 fn check_snippet(ra_fixture: &str, expect: Expect) {
57 let actual = completion_list(ra_fixture, CompletionKind::Snippet);
58 expect.assert_eq(&actual)
59 }
60
52 #[test] 61 #[test]
53 fn completes_enum_variants_and_modules() { 62 fn completes_enum_variants_and_modules() {
54 check( 63 check(
@@ -69,7 +78,7 @@ fn foo() {
69 en E 78 en E
70 ct Z 79 ct Z
71 st Bar 80 st Bar
72 ev X () 81 ev X
73 md m 82 md m
74 "#]], 83 "#]],
75 ); 84 );
@@ -114,4 +123,139 @@ fn foo() {
114 "#]], 123 "#]],
115 ); 124 );
116 } 125 }
126
127 #[test]
128 fn completes_in_param() {
129 check(
130 r#"
131enum E { X }
132
133static FOO: E = E::X;
134struct Bar { f: u32 }
135
136fn foo(<|>) {
137}
138"#,
139 expect![[r#"
140 st Bar
141 "#]],
142 );
143 }
144
145 #[test]
146 fn completes_pat_in_let() {
147 check_snippet(
148 r#"
149struct Bar { f: u32 }
150
151fn foo() {
152 let <|>
153}
154"#,
155 expect![[r#"
156 bn Bar Bar { f$1 }$0
157 "#]],
158 );
159 }
160
161 #[test]
162 fn completes_param_pattern() {
163 check_snippet(
164 r#"
165struct Foo { bar: String, baz: String }
166struct Bar(String, String);
167struct Baz;
168fn outer(<|>) {}
169"#,
170 expect![[r#"
171 bn Foo Foo { bar$1, baz$2 }: Foo$0
172 bn Bar Bar($1, $2): Bar$0
173 "#]],
174 )
175 }
176
177 #[test]
178 fn completes_let_pattern() {
179 check_snippet(
180 r#"
181struct Foo { bar: String, baz: String }
182struct Bar(String, String);
183struct Baz;
184fn outer() {
185 let <|>
186}
187"#,
188 expect![[r#"
189 bn Foo Foo { bar$1, baz$2 }$0
190 bn Bar Bar($1, $2)$0
191 "#]],
192 )
193 }
194
195 #[test]
196 fn completes_refutable_pattern() {
197 check_snippet(
198 r#"
199struct Foo { bar: i32, baz: i32 }
200struct Bar(String, String);
201struct Baz;
202fn outer() {
203 match () {
204 <|>
205 }
206}
207"#,
208 expect![[r#"
209 bn Foo Foo { bar$1, baz$2 }$0
210 bn Bar Bar($1, $2)$0
211 "#]],
212 )
213 }
214
215 #[test]
216 fn omits_private_fields_pat() {
217 check_snippet(
218 r#"
219mod foo {
220 pub struct Foo { pub bar: i32, baz: i32 }
221 pub struct Bar(pub String, String);
222 pub struct Invisible(String, String);
223}
224use foo::*;
225
226fn outer() {
227 match () {
228 <|>
229 }
230}
231"#,
232 expect![[r#"
233 bn Foo Foo { bar$1, .. }$0
234 bn Bar Bar($1, ..)$0
235 "#]],
236 )
237 }
238
239 #[test]
240 fn only_shows_ident_completion() {
241 check_edit(
242 "Foo",
243 r#"
244struct Foo(i32);
245fn main() {
246 match Foo(92) {
247 <|>(92) => (),
248 }
249}
250"#,
251 r#"
252struct Foo(i32);
253fn main() {
254 match Foo(92) {
255 Foo(92) => (),
256 }
257}
258"#,
259 );
260 }
117} 261}