@@ -19,8 +19,10 @@ use crate::{
19
19
} ;
20
20
21
21
/// `CompletionItem` describes a single completion entity which expands to 1 or more entries in the
22
- /// editor pop-up. It is basically a POD with various properties. To construct a
23
- /// [`CompletionItem`], use [`Builder::new`] method and the [`Builder`] struct.
22
+ /// editor pop-up.
23
+ ///
24
+ /// It is basically a POD with various properties. To construct a [`CompletionItem`],
25
+ /// use [`Builder::new`] method and the [`Builder`] struct.
24
26
#[ derive( Clone ) ]
25
27
#[ non_exhaustive]
26
28
pub struct CompletionItem {
@@ -129,7 +131,8 @@ impl fmt::Debug for CompletionItem {
129
131
130
132
#[ derive( Debug , Clone , Copy , Eq , PartialEq , Default ) ]
131
133
pub struct CompletionRelevance {
132
- /// This is set in cases like these:
134
+ /// This is set when the identifier being completed matches up with the name that is expected,
135
+ /// like in a function argument.
133
136
///
134
137
/// ```
135
138
/// fn f(spam: String) {}
@@ -139,9 +142,9 @@ pub struct CompletionRelevance {
139
142
/// }
140
143
/// ```
141
144
pub exact_name_match : bool ,
142
- /// See CompletionRelevanceTypeMatch doc comments for cases where this is set .
145
+ /// See [` CompletionRelevanceTypeMatch`] .
143
146
pub type_match : Option < CompletionRelevanceTypeMatch > ,
144
- /// This is set in cases like these:
147
+ /// Set for local variables.
145
148
///
146
149
/// ```
147
150
/// fn foo(a: u32) {
@@ -150,25 +153,26 @@ pub struct CompletionRelevance {
150
153
/// }
151
154
/// ```
152
155
pub is_local : bool ,
153
- /// This is set when trait items are completed in an impl of that trait.
154
- pub is_item_from_trait : bool ,
155
- /// This is set for when trait items are from traits with `#[doc(notable_trait)]`
156
- pub is_item_from_notable_trait : bool ,
157
- /// This is set when an import is suggested whose name is already imported.
156
+ /// Populated when the completion item comes from a trait (impl).
157
+ pub trait_ : Option < CompletionRelevanceTraitInfo > ,
158
+ /// This is set when an import is suggested in a use item whose name is already imported.
158
159
pub is_name_already_imported : bool ,
159
160
/// This is set for completions that will insert a `use` item.
160
161
pub requires_import : bool ,
161
- /// Set for method completions of the `core::ops` and `core::cmp` family.
162
- pub is_op_method : bool ,
163
162
/// Set for item completions that are private but in the workspace.
164
163
pub is_private_editable : bool ,
165
164
/// Set for postfix snippet item completions
166
165
pub postfix_match : Option < CompletionRelevancePostfixMatch > ,
167
- /// This is set for type inference results
168
- pub is_definite : bool ,
169
166
/// This is set for items that are function (associated or method)
170
167
pub function : Option < CompletionRelevanceFn > ,
171
168
}
169
+ #[ derive( Debug , Clone , Copy , Eq , PartialEq ) ]
170
+ pub struct CompletionRelevanceTraitInfo {
171
+ /// The trait this item is from is a `#[doc(notable_trait)]`
172
+ pub notable_trait : bool ,
173
+ /// Set for method completions of the `core::ops` and `core::cmp` family.
174
+ pub is_op_method : bool ,
175
+ }
172
176
173
177
#[ derive( Debug , Clone , Copy , Eq , PartialEq ) ]
174
178
pub enum CompletionRelevanceTypeMatch {
@@ -182,7 +186,7 @@ pub enum CompletionRelevanceTypeMatch {
182
186
/// }
183
187
/// ```
184
188
CouldUnify ,
185
- /// This is set in cases like these :
189
+ /// This is set in cases where the type matches the expected type, like :
186
190
///
187
191
/// ```
188
192
/// fn f(spam: String) {}
@@ -238,90 +242,82 @@ impl CompletionRelevance {
238
242
/// See is_relevant if you need to make some judgement about score
239
243
/// in an absolute sense.
240
244
pub fn score ( self ) -> u32 {
241
- let mut score = 0 ;
245
+ let mut score = ! 0 / 2 ;
242
246
let CompletionRelevance {
243
247
exact_name_match,
244
248
type_match,
245
249
is_local,
246
- is_item_from_trait,
247
250
is_name_already_imported,
248
251
requires_import,
249
- is_op_method,
250
252
is_private_editable,
251
253
postfix_match,
252
- is_definite,
253
- is_item_from_notable_trait,
254
+ trait_,
254
255
function,
255
256
} = self ;
256
257
258
+ // only applicable for completions within use items
259
+ // lower rank for conflicting import names
260
+ if is_name_already_imported {
261
+ score -= 1 ;
262
+ }
263
+ // slightly prefer locals
264
+ if is_local {
265
+ score += 1 ;
266
+ }
267
+
257
268
// lower rank private things
258
269
if !is_private_editable {
259
270
score += 1 ;
260
271
}
261
- // lower rank trait op methods
262
- if !is_op_method {
263
- score += 10 ;
272
+
273
+ if let Some ( trait_) = trait_ {
274
+ // lower rank trait methods unless its notable
275
+ if !trait_. notable_trait {
276
+ score -= 5 ;
277
+ }
278
+ // lower rank trait op methods
279
+ if trait_. is_op_method {
280
+ score -= 5 ;
281
+ }
264
282
}
265
- // lower rank for conflicting import names
266
- if !is_name_already_imported {
267
- score += 1 ;
268
- }
269
- // lower rank for items that don't need an import
270
- if !requires_import {
271
- score += 1 ;
283
+ // lower rank for items that need an import
284
+ if requires_import {
285
+ score -= 1 ;
272
286
}
273
287
if exact_name_match {
274
- score += 10 ;
288
+ score += 20 ;
275
289
}
276
- score += match postfix_match {
277
- Some ( CompletionRelevancePostfixMatch :: Exact ) => 100 ,
278
- Some ( CompletionRelevancePostfixMatch :: NonExact ) => 0 ,
279
- None => 3 ,
290
+ match postfix_match {
291
+ Some ( CompletionRelevancePostfixMatch :: Exact ) => score += 100 ,
292
+ Some ( CompletionRelevancePostfixMatch :: NonExact ) => score -= 5 ,
293
+ None => ( ) ,
280
294
} ;
281
295
score += match type_match {
282
- Some ( CompletionRelevanceTypeMatch :: Exact ) => 8 ,
283
- Some ( CompletionRelevanceTypeMatch :: CouldUnify ) => 3 ,
296
+ Some ( CompletionRelevanceTypeMatch :: Exact ) => 18 ,
297
+ Some ( CompletionRelevanceTypeMatch :: CouldUnify ) => 5 ,
284
298
None => 0 ,
285
299
} ;
286
- // slightly prefer locals
287
- if is_local {
288
- score += 1 ;
289
- }
290
- if is_item_from_trait {
291
- score += 1 ;
292
- }
293
- if is_item_from_notable_trait {
294
- score += 1 ;
295
- }
296
- if is_definite {
297
- score += 10 ;
298
- }
299
-
300
- score += function
301
- . map ( |asf| {
302
- let mut fn_score = match asf. return_type {
303
- CompletionRelevanceReturnType :: DirectConstructor => 15 ,
304
- CompletionRelevanceReturnType :: Builder => 10 ,
305
- CompletionRelevanceReturnType :: Constructor => 5 ,
306
- CompletionRelevanceReturnType :: Other => 0 ,
307
- } ;
308
-
309
- // When a fn is bumped due to return type:
310
- // Bump Constructor or Builder methods with no arguments,
311
- // over them than with self arguments
312
- if fn_score > 0 {
313
- if !asf. has_params {
314
- // bump associated functions
315
- fn_score += 1 ;
316
- } else if asf. has_self_param {
317
- // downgrade methods (below Constructor)
318
- fn_score = 1 ;
319
- }
320
- }
300
+ if let Some ( function) = function {
301
+ let mut fn_score = match function. return_type {
302
+ CompletionRelevanceReturnType :: DirectConstructor => 15 ,
303
+ CompletionRelevanceReturnType :: Builder => 10 ,
304
+ CompletionRelevanceReturnType :: Constructor => 5 ,
305
+ CompletionRelevanceReturnType :: Other => 0u32 ,
306
+ } ;
307
+
308
+ // When a fn is bumped due to return type:
309
+ // Bump Constructor or Builder methods with no arguments,
310
+ // over them than with self arguments
311
+ if function. has_params {
312
+ // bump associated functions
313
+ fn_score = fn_score. saturating_sub ( 1 ) ;
314
+ } else if function. has_self_param {
315
+ // downgrade methods (below Constructor)
316
+ fn_score = fn_score. min ( 1 ) ;
317
+ }
321
318
322
- fn_score
323
- } )
324
- . unwrap_or_default ( ) ;
319
+ score += fn_score;
320
+ } ;
325
321
326
322
score
327
323
}
@@ -701,8 +697,21 @@ mod tests {
701
697
// that any items in the same vec have the same score.
702
698
let expected_relevance_order = vec ! [
703
699
vec![ ] ,
704
- vec![ Cr { is_op_method: true , is_private_editable: true , ..default } ] ,
705
- vec![ Cr { is_op_method: true , ..default } ] ,
700
+ vec![ Cr {
701
+ trait_: Some ( crate :: item:: CompletionRelevanceTraitInfo {
702
+ notable_trait: false ,
703
+ is_op_method: true ,
704
+ } ) ,
705
+ is_private_editable: true ,
706
+ ..default
707
+ } ] ,
708
+ vec![ Cr {
709
+ trait_: Some ( crate :: item:: CompletionRelevanceTraitInfo {
710
+ notable_trait: false ,
711
+ is_op_method: true ,
712
+ } ) ,
713
+ ..default
714
+ } ] ,
706
715
vec![ Cr { postfix_match: Some ( CompletionRelevancePostfixMatch :: NonExact ) , ..default } ] ,
707
716
vec![ Cr { is_private_editable: true , ..default } ] ,
708
717
vec![ default ] ,
0 commit comments