diff options
Diffstat (limited to 'crates/ide_completion/src/item.rs')
-rw-r--r-- | crates/ide_completion/src/item.rs | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs index 5e8ed75f1..14afec603 100644 --- a/crates/ide_completion/src/item.rs +++ b/crates/ide_completion/src/item.rs | |||
@@ -63,8 +63,14 @@ pub struct CompletionItem { | |||
63 | /// after completion. | 63 | /// after completion. |
64 | trigger_call_info: bool, | 64 | trigger_call_info: bool, |
65 | 65 | ||
66 | /// Score is useful to pre select or display in better order completion items | 66 | /// We use this to sort completion. Relevance records facts like "do the |
67 | score: Option<CompletionScore>, | 67 | /// types align precisely?". We can't sort by relevances directly, they are |
68 | /// only partially ordered. | ||
69 | /// | ||
70 | /// Note that Relevance ignores fuzzy match score. We compute Relevance for | ||
71 | /// all possible items, and then separately build an ordered completion list | ||
72 | /// based on relevance and fuzzy matching with the already typed identifier. | ||
73 | relevance: Relevance, | ||
68 | 74 | ||
69 | /// Indicates that a reference or mutable reference to this variable is a | 75 | /// Indicates that a reference or mutable reference to this variable is a |
70 | /// possible match. | 76 | /// possible match. |
@@ -101,8 +107,8 @@ impl fmt::Debug for CompletionItem { | |||
101 | if self.deprecated { | 107 | if self.deprecated { |
102 | s.field("deprecated", &true); | 108 | s.field("deprecated", &true); |
103 | } | 109 | } |
104 | if let Some(score) = &self.score { | 110 | if self.relevance.is_relevant() { |
105 | s.field("score", score); | 111 | s.field("relevance", &self.relevance); |
106 | } | 112 | } |
107 | if let Some(mutability) = &self.ref_match { | 113 | if let Some(mutability) = &self.ref_match { |
108 | s.field("ref_match", &format!("&{}", mutability.as_keyword_for_ref())); | 114 | s.field("ref_match", &format!("&{}", mutability.as_keyword_for_ref())); |
@@ -122,6 +128,36 @@ pub enum CompletionScore { | |||
122 | TypeAndNameMatch, | 128 | TypeAndNameMatch, |
123 | } | 129 | } |
124 | 130 | ||
131 | #[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Default)] | ||
132 | pub struct Relevance { | ||
133 | /// This is set in cases like these: | ||
134 | /// | ||
135 | /// ``` | ||
136 | /// fn f(spam: String) {} | ||
137 | /// fn main { | ||
138 | /// let spam = 92; | ||
139 | /// f($0) // name of local matches the name of param | ||
140 | /// } | ||
141 | /// ``` | ||
142 | pub exact_name_match: bool, | ||
143 | /// This is set in cases like these: | ||
144 | /// | ||
145 | /// ``` | ||
146 | /// fn f(spam: String) {} | ||
147 | /// fn main { | ||
148 | /// let foo = String::new(); | ||
149 | /// f($0) // type of local matches the type of param | ||
150 | /// } | ||
151 | /// ``` | ||
152 | pub exact_type_match: bool, | ||
153 | } | ||
154 | |||
155 | impl Relevance { | ||
156 | pub fn is_relevant(&self) -> bool { | ||
157 | self != &Relevance::default() | ||
158 | } | ||
159 | } | ||
160 | |||
125 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 161 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
126 | pub enum CompletionItemKind { | 162 | pub enum CompletionItemKind { |
127 | SymbolKind(SymbolKind), | 163 | SymbolKind(SymbolKind), |
@@ -213,7 +249,7 @@ impl CompletionItem { | |||
213 | text_edit: None, | 249 | text_edit: None, |
214 | deprecated: false, | 250 | deprecated: false, |
215 | trigger_call_info: None, | 251 | trigger_call_info: None, |
216 | score: None, | 252 | relevance: Relevance::default(), |
217 | ref_match: None, | 253 | ref_match: None, |
218 | import_to_add: None, | 254 | import_to_add: None, |
219 | } | 255 | } |
@@ -256,8 +292,8 @@ impl CompletionItem { | |||
256 | self.deprecated | 292 | self.deprecated |
257 | } | 293 | } |
258 | 294 | ||
259 | pub fn score(&self) -> Option<CompletionScore> { | 295 | pub fn relevance(&self) -> Relevance { |
260 | self.score | 296 | self.relevance |
261 | } | 297 | } |
262 | 298 | ||
263 | pub fn trigger_call_info(&self) -> bool { | 299 | pub fn trigger_call_info(&self) -> bool { |
@@ -313,7 +349,7 @@ pub(crate) struct Builder { | |||
313 | text_edit: Option<TextEdit>, | 349 | text_edit: Option<TextEdit>, |
314 | deprecated: bool, | 350 | deprecated: bool, |
315 | trigger_call_info: Option<bool>, | 351 | trigger_call_info: Option<bool>, |
316 | score: Option<CompletionScore>, | 352 | relevance: Relevance, |
317 | ref_match: Option<Mutability>, | 353 | ref_match: Option<Mutability>, |
318 | } | 354 | } |
319 | 355 | ||
@@ -360,7 +396,7 @@ impl Builder { | |||
360 | completion_kind: self.completion_kind, | 396 | completion_kind: self.completion_kind, |
361 | deprecated: self.deprecated, | 397 | deprecated: self.deprecated, |
362 | trigger_call_info: self.trigger_call_info.unwrap_or(false), | 398 | trigger_call_info: self.trigger_call_info.unwrap_or(false), |
363 | score: self.score, | 399 | relevance: self.relevance, |
364 | ref_match: self.ref_match, | 400 | ref_match: self.ref_match, |
365 | import_to_add: self.import_to_add, | 401 | import_to_add: self.import_to_add, |
366 | } | 402 | } |
@@ -421,8 +457,8 @@ impl Builder { | |||
421 | self.deprecated = deprecated; | 457 | self.deprecated = deprecated; |
422 | self | 458 | self |
423 | } | 459 | } |
424 | pub(crate) fn set_score(mut self, score: CompletionScore) -> Builder { | 460 | pub(crate) fn set_relevance(mut self, relevance: Relevance) -> Builder { |
425 | self.score = Some(score); | 461 | self.relevance = relevance; |
426 | self | 462 | self |
427 | } | 463 | } |
428 | pub(crate) fn trigger_call_info(mut self) -> Builder { | 464 | pub(crate) fn trigger_call_info(mut self) -> Builder { |