aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion/complete_dot.rs
diff options
context:
space:
mode:
authorBenjamin Coenen <[email protected]>2020-04-16 17:30:08 +0100
committerBenjamin Coenen <[email protected]>2020-04-16 17:30:08 +0100
commit6ebc8bbeb005f5d3f2b00d1ae1f1804116e3a8f5 (patch)
tree9b0ea7f19402ee17602e7b38d934ae19301e2dee /crates/ra_ide/src/completion/complete_dot.rs
parent06076f95a7ca764696b055eb754e163f884eefaa (diff)
feat: improve dot completions with scoring
Signed-off-by: Benjamin Coenen <[email protected]>
Diffstat (limited to 'crates/ra_ide/src/completion/complete_dot.rs')
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs114
1 files changed, 43 insertions, 71 deletions
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index 2e228b638..174b39964 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -6,12 +6,11 @@ use hir::{
6 Type, 6 Type,
7}; 7};
8 8
9use crate::completion::completion_item::CompletionKind;
10use crate::{ 9use crate::{
11 call_info::call_info, 10 call_info::call_info,
12 completion::{ 11 completion::{
13 completion_context::CompletionContext, 12 completion_context::CompletionContext,
14 completion_item::{Completions, SortOption}, 13 completion_item::{CompletionKind, Completions, ScoreOption},
15 }, 14 },
16 // CallInfo, 15 // CallInfo,
17 CompletionItem, 16 CompletionItem,
@@ -49,40 +48,12 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Ty
49 for receiver in receiver.autoderef(ctx.db) { 48 for receiver in receiver.autoderef(ctx.db) {
50 let fields = receiver.fields(ctx.db); 49 let fields = receiver.fields(ctx.db);
51 50
52 // If we use this implementation we can delete call_info in the CompletionContext
53 if let Some(record_field) = &ctx.record_field_syntax { 51 if let Some(record_field) = &ctx.record_field_syntax {
54 acc.with_sort_option(SortOption::RecordField(record_field.clone())); 52 acc.with_score_option(ScoreOption::RecordField(record_field.clone()));
55 } else if let Some(call_info) = call_info(ctx.db, ctx.file_position) { 53 } else if let Some(call_info) = call_info(ctx.db, ctx.file_position) {
56 acc.with_sort_option(SortOption::CallFn(call_info)); 54 acc.with_score_option(ScoreOption::CallFn(call_info));
57 } 55 }
58 56
59 // // For Call Fn
60 // if let Some(call_info) = &ctx.call_info {
61 // if let Some(active_parameter_type) = call_info.active_parameter_type() {
62 // let active_parameter_name = call_info.active_parameter_name().unwrap();
63 // fields.sort_by(|a, b| {
64 // // For the same type
65 // if active_parameter_type == a.1.display(ctx.db).to_string() {
66 // // If same type + same name then go top position
67 // if active_parameter_name == a.0.name(ctx.db).to_string() {
68 // Ordering::Less
69 // } else {
70 // if active_parameter_type == b.1.display(ctx.db).to_string() {
71 // Ordering::Equal
72 // } else {
73 // Ordering::Less
74 // }
75 // }
76 // } else {
77 // Ordering::Greater
78 // }
79 // });
80 // }
81 // }
82
83 // For Lit struct fields
84 // ---
85
86 for (field, ty) in fields { 57 for (field, ty) in fields {
87 if ctx.scope().module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) { 58 if ctx.scope().module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) {
88 // Skip private field. FIXME: If the definition location of the 59 // Skip private field. FIXME: If the definition location of the
@@ -116,20 +87,13 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &T
116 87
117#[cfg(test)] 88#[cfg(test)]
118mod tests { 89mod tests {
119 use crate::completion::{ 90 use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
120 test_utils::{do_completion, do_completion_without_sort},
121 CompletionItem, CompletionKind,
122 };
123 use insta::assert_debug_snapshot; 91 use insta::assert_debug_snapshot;
124 92
125 fn do_ref_completion(code: &str) -> Vec<CompletionItem> { 93 fn do_ref_completion(code: &str) -> Vec<CompletionItem> {
126 do_completion(code, CompletionKind::Reference) 94 do_completion(code, CompletionKind::Reference)
127 } 95 }
128 96
129 fn do_ref_completion_without_sort(code: &str) -> Vec<CompletionItem> {
130 do_completion_without_sort(code, CompletionKind::Reference)
131 }
132
133 #[test] 97 #[test]
134 fn test_struct_field_completion() { 98 fn test_struct_field_completion() {
135 assert_debug_snapshot!( 99 assert_debug_snapshot!(
@@ -159,7 +123,7 @@ mod tests {
159 #[test] 123 #[test]
160 fn test_struct_field_completion_in_func_call() { 124 fn test_struct_field_completion_in_func_call() {
161 assert_debug_snapshot!( 125 assert_debug_snapshot!(
162 do_ref_completion_without_sort( 126 do_ref_completion(
163 r" 127 r"
164 struct A { another_field: i64, the_field: u32, my_string: String } 128 struct A { another_field: i64, the_field: u32, my_string: String }
165 fn test(my_param: u32) -> u32 { my_param } 129 fn test(my_param: u32) -> u32 { my_param }
@@ -171,14 +135,6 @@ mod tests {
171 @r###" 135 @r###"
172 [ 136 [
173 CompletionItem { 137 CompletionItem {
174 label: "the_field",
175 source_range: [201; 201),
176 delete: [201; 201),
177 insert: "the_field",
178 kind: Field,
179 detail: "u32",
180 },
181 CompletionItem {
182 label: "another_field", 138 label: "another_field",
183 source_range: [201; 201), 139 source_range: [201; 201),
184 delete: [201; 201), 140 delete: [201; 201),
@@ -194,6 +150,15 @@ mod tests {
194 kind: Field, 150 kind: Field,
195 detail: "{unknown}", 151 detail: "{unknown}",
196 }, 152 },
153 CompletionItem {
154 label: "the_field",
155 source_range: [201; 201),
156 delete: [201; 201),
157 insert: "the_field",
158 kind: Field,
159 detail: "u32",
160 score: TypeMatch,
161 },
197 ] 162 ]
198 "### 163 "###
199 ); 164 );
@@ -202,7 +167,7 @@ mod tests {
202 #[test] 167 #[test]
203 fn test_struct_field_completion_in_func_call_with_type_and_name() { 168 fn test_struct_field_completion_in_func_call_with_type_and_name() {
204 assert_debug_snapshot!( 169 assert_debug_snapshot!(
205 do_ref_completion_without_sort( 170 do_ref_completion(
206 r" 171 r"
207 struct A { another_field: i64, another_good_type: u32, the_field: u32 } 172 struct A { another_field: i64, another_good_type: u32, the_field: u32 }
208 fn test(the_field: u32) -> u32 { the_field } 173 fn test(the_field: u32) -> u32 { the_field }
@@ -214,12 +179,12 @@ mod tests {
214 @r###" 179 @r###"
215 [ 180 [
216 CompletionItem { 181 CompletionItem {
217 label: "the_field", 182 label: "another_field",
218 source_range: [208; 208), 183 source_range: [208; 208),
219 delete: [208; 208), 184 delete: [208; 208),
220 insert: "the_field", 185 insert: "another_field",
221 kind: Field, 186 kind: Field,
222 detail: "u32", 187 detail: "i64",
223 }, 188 },
224 CompletionItem { 189 CompletionItem {
225 label: "another_good_type", 190 label: "another_good_type",
@@ -228,14 +193,16 @@ mod tests {
228 insert: "another_good_type", 193 insert: "another_good_type",
229 kind: Field, 194 kind: Field,
230 detail: "u32", 195 detail: "u32",
196 score: TypeMatch,
231 }, 197 },
232 CompletionItem { 198 CompletionItem {
233 label: "another_field", 199 label: "the_field",
234 source_range: [208; 208), 200 source_range: [208; 208),
235 delete: [208; 208), 201 delete: [208; 208),
236 insert: "another_field", 202 insert: "the_field",
237 kind: Field, 203 kind: Field,
238 detail: "i64", 204 detail: "u32",
205 score: TypeAndNameMatch,
239 }, 206 },
240 ] 207 ]
241 "### 208 "###
@@ -245,7 +212,7 @@ mod tests {
245 #[test] 212 #[test]
246 fn test_struct_field_completion_in_record_lit() { 213 fn test_struct_field_completion_in_record_lit() {
247 assert_debug_snapshot!( 214 assert_debug_snapshot!(
248 do_ref_completion_without_sort( 215 do_ref_completion(
249 r" 216 r"
250 struct A { another_field: i64, another_good_type: u32, the_field: u32 } 217 struct A { another_field: i64, another_good_type: u32, the_field: u32 }
251 struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 } 218 struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 }
@@ -259,12 +226,12 @@ mod tests {
259 @r###" 226 @r###"
260 [ 227 [
261 CompletionItem { 228 CompletionItem {
262 label: "the_field", 229 label: "another_field",
263 source_range: [270; 270), 230 source_range: [270; 270),
264 delete: [270; 270), 231 delete: [270; 270),
265 insert: "the_field", 232 insert: "another_field",
266 kind: Field, 233 kind: Field,
267 detail: "u32", 234 detail: "i64",
268 }, 235 },
269 CompletionItem { 236 CompletionItem {
270 label: "another_good_type", 237 label: "another_good_type",
@@ -273,14 +240,16 @@ mod tests {
273 insert: "another_good_type", 240 insert: "another_good_type",
274 kind: Field, 241 kind: Field,
275 detail: "u32", 242 detail: "u32",
243 score: TypeMatch,
276 }, 244 },
277 CompletionItem { 245 CompletionItem {
278 label: "another_field", 246 label: "the_field",
279 source_range: [270; 270), 247 source_range: [270; 270),
280 delete: [270; 270), 248 delete: [270; 270),
281 insert: "another_field", 249 insert: "the_field",
282 kind: Field, 250 kind: Field,
283 detail: "i64", 251 detail: "u32",
252 score: TypeAndNameMatch,
284 }, 253 },
285 ] 254 ]
286 "### 255 "###
@@ -290,7 +259,7 @@ mod tests {
290 #[test] 259 #[test]
291 fn test_struct_field_completion_in_record_lit_and_fn_call() { 260 fn test_struct_field_completion_in_record_lit_and_fn_call() {
292 assert_debug_snapshot!( 261 assert_debug_snapshot!(
293 do_ref_completion_without_sort( 262 do_ref_completion(
294 r" 263 r"
295 struct A { another_field: i64, another_good_type: u32, the_field: u32 } 264 struct A { another_field: i64, another_good_type: u32, the_field: u32 }
296 struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 } 265 struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 }
@@ -311,6 +280,7 @@ mod tests {
311 insert: "another_field", 280 insert: "another_field",
312 kind: Field, 281 kind: Field,
313 detail: "i64", 282 detail: "i64",
283 score: TypeMatch,
314 }, 284 },
315 CompletionItem { 285 CompletionItem {
316 label: "another_good_type", 286 label: "another_good_type",
@@ -336,7 +306,7 @@ mod tests {
336 #[test] 306 #[test]
337 fn test_struct_field_completion_in_fn_call_and_record_lit() { 307 fn test_struct_field_completion_in_fn_call_and_record_lit() {
338 assert_debug_snapshot!( 308 assert_debug_snapshot!(
339 do_ref_completion_without_sort( 309 do_ref_completion(
340 r" 310 r"
341 struct A { another_field: i64, another_good_type: u32, the_field: u32 } 311 struct A { another_field: i64, another_good_type: u32, the_field: u32 }
342 struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 } 312 struct B { my_string: String, my_vec: Vec<u32>, the_field: u32 }
@@ -351,12 +321,12 @@ mod tests {
351 @r###" 321 @r###"
352 [ 322 [
353 CompletionItem { 323 CompletionItem {
354 label: "the_field", 324 label: "another_field",
355 source_range: [328; 328), 325 source_range: [328; 328),
356 delete: [328; 328), 326 delete: [328; 328),
357 insert: "the_field", 327 insert: "another_field",
358 kind: Field, 328 kind: Field,
359 detail: "u32", 329 detail: "i64",
360 }, 330 },
361 CompletionItem { 331 CompletionItem {
362 label: "another_good_type", 332 label: "another_good_type",
@@ -365,14 +335,16 @@ mod tests {
365 insert: "another_good_type", 335 insert: "another_good_type",
366 kind: Field, 336 kind: Field,
367 detail: "u32", 337 detail: "u32",
338 score: TypeMatch,
368 }, 339 },
369 CompletionItem { 340 CompletionItem {
370 label: "another_field", 341 label: "the_field",
371 source_range: [328; 328), 342 source_range: [328; 328),
372 delete: [328; 328), 343 delete: [328; 328),
373 insert: "another_field", 344 insert: "the_field",
374 kind: Field, 345 kind: Field,
375 detail: "i64", 346 detail: "u32",
347 score: TypeAndNameMatch,
376 }, 348 },
377 ] 349 ]
378 "### 350 "###