@@ -174,10 +174,10 @@ pub fn find_best_match_for_name(
174
174
fn find_best_match_for_name_impl (
175
175
use_substring_score : bool ,
176
176
candidates : & [ Symbol ] ,
177
- lookup : Symbol ,
177
+ lookup_symbol : Symbol ,
178
178
dist : Option < usize > ,
179
179
) -> Option < Symbol > {
180
- let lookup = lookup . as_str ( ) ;
180
+ let lookup = lookup_symbol . as_str ( ) ;
181
181
let lookup_uppercase = lookup. to_uppercase ( ) ;
182
182
183
183
// Priority of matches:
@@ -190,6 +190,8 @@ fn find_best_match_for_name_impl(
190
190
191
191
let mut dist = dist. unwrap_or_else ( || cmp:: max ( lookup. len ( ) , 3 ) / 3 ) ;
192
192
let mut best = None ;
193
+ // store the candidates with the same distance, only for `use_substring_score` current.
194
+ let mut next_candidates = vec ! [ ] ;
193
195
for c in candidates {
194
196
match if use_substring_score {
195
197
edit_distance_with_substrings ( lookup, c. as_str ( ) , dist)
@@ -198,12 +200,36 @@ fn find_best_match_for_name_impl(
198
200
} {
199
201
Some ( 0 ) => return Some ( * c) ,
200
202
Some ( d) => {
201
- dist = d - 1 ;
203
+ if use_substring_score {
204
+ if d < dist {
205
+ dist = d;
206
+ next_candidates. clear ( ) ;
207
+ } else {
208
+ // `d == dist` here, we need to store the candidates with the same distance
209
+ // so we won't decrease the distance in the next loop.
210
+ }
211
+ next_candidates. push ( * c) ;
212
+ } else {
213
+ dist = d - 1 ;
214
+ }
202
215
best = Some ( * c) ;
203
216
}
204
217
None => { }
205
218
}
206
219
}
220
+
221
+ // We have a tie among several candidates, try to select the best among them ignoring substrings.
222
+ // For example, the candidates list `force_capture`, `capture`, and user inputed `forced_capture`,
223
+ // we select `force_capture` with a extra round of edit distance calculation.
224
+ if next_candidates. len ( ) > 1 {
225
+ debug_assert ! ( use_substring_score) ;
226
+ best = find_best_match_for_name_impl (
227
+ false ,
228
+ & next_candidates,
229
+ lookup_symbol,
230
+ Some ( lookup. len ( ) ) ,
231
+ ) ;
232
+ }
207
233
if best. is_some ( ) {
208
234
return best;
209
235
}
0 commit comments