1
1
// TODO: refactor this heresy
2
2
3
3
use crate :: frecency:: FrecencyTracker ;
4
+ use crate :: lsp_item:: LspItem ;
4
5
use mlua:: prelude:: * ;
5
6
use mlua:: FromLua ;
6
7
use mlua:: Lua ;
7
- use serde :: { Deserialize , Serialize } ;
8
+ use std :: cell :: LazyCell ;
8
9
use std:: cmp:: Reverse ;
9
10
use std:: collections:: HashSet ;
10
11
11
- #[ derive( Clone , Serialize , Deserialize , Debug ) ]
12
- pub struct LspItem {
13
- pub label : String ,
14
- #[ serde( rename = "sortText" ) ]
15
- pub sort_text : Option < String > ,
16
- #[ serde( rename = "filterText" ) ]
17
- pub filter_text : Option < String > ,
18
- pub kind : u32 ,
19
- pub score_offset : Option < i32 > ,
20
- pub source_id : String ,
21
- }
22
-
23
- impl FromLua < ' _ > for LspItem {
24
- fn from_lua ( value : LuaValue < ' _ > , _lua : & ' _ Lua ) -> LuaResult < Self > {
25
- if let Some ( tab) = value. as_table ( ) {
26
- let label: String = tab. get ( "label" ) . unwrap_or_default ( ) ;
27
- let sort_text: Option < String > = tab. get ( "sortText" ) . ok ( ) ;
28
- let filter_text: Option < String > = tab. get ( "filterText" ) . ok ( ) ;
29
- let kind: u32 = tab. get ( "kind" ) . unwrap_or_default ( ) ;
30
- let score_offset: Option < i32 > = tab. get ( "score_offset" ) . ok ( ) ;
31
- let source_id: String = tab. get ( "source_id" ) . unwrap_or_default ( ) ;
32
-
33
- Ok ( LspItem {
34
- label,
35
- sort_text,
36
- filter_text,
37
- kind,
38
- score_offset,
39
- source_id,
40
- } )
41
- } else {
42
- Err ( mlua:: Error :: FromLuaConversionError {
43
- from : "LuaValue" ,
44
- to : "LspItem" ,
45
- message : None ,
46
- } )
47
- }
48
- }
49
- }
50
-
51
- #[ derive( Clone , Serialize , Deserialize ) ]
52
- pub struct MatchedLspItem {
53
- label : String ,
54
- kind : u32 ,
55
- index : u32 ,
56
- score : i32 ,
57
- }
58
-
59
- #[ derive( Clone , Serialize , Deserialize , Hash ) ]
12
+ #[ derive( Clone , Hash ) ]
60
13
pub struct FuzzyOptions {
61
14
use_typo_resistance : bool ,
62
15
use_frecency : bool ,
@@ -99,30 +52,33 @@ impl FromLua<'_> for FuzzyOptions {
99
52
100
53
pub fn fuzzy (
101
54
needle : String ,
102
- haystack : Vec < LspItem > ,
55
+ haystack_labels : Vec < String > ,
56
+ haystack : Vec < LuaTable > ,
103
57
frecency : & FrecencyTracker ,
104
58
opts : FuzzyOptions ,
105
59
) -> Vec < usize > {
60
+ let haystack = haystack
61
+ . into_iter ( )
62
+ . map ( |item| LazyCell :: new ( move || -> LspItem { item. into ( ) } ) )
63
+ . collect :: < Vec < _ > > ( ) ;
64
+
106
65
let nearby_words: HashSet < String > = HashSet :: from_iter ( opts. nearby_words . unwrap_or_default ( ) ) ;
107
66
108
67
// Fuzzy match with fzrs
109
- let haystack_labels = haystack
110
- . iter ( )
111
- . map ( |s| {
112
- if let Some ( filter_text) = & s. filter_text {
113
- filter_text. as_str ( )
114
- } else {
115
- s. label . as_str ( )
116
- }
117
- } )
118
- . collect :: < Vec < _ > > ( ) ;
119
68
let options = frizbee:: Options {
120
69
prefilter : !opts. use_typo_resistance ,
121
70
min_score : opts. min_score ,
122
71
stable_sort : false ,
123
72
..Default :: default ( )
124
73
} ;
125
- let mut matches = frizbee:: match_list ( & needle, & haystack_labels, options) ;
74
+ let mut matches = frizbee:: match_list (
75
+ & needle,
76
+ & haystack_labels
77
+ . iter ( )
78
+ . map ( |s| s. as_str ( ) )
79
+ . collect :: < Vec < _ > > ( ) ,
80
+ options,
81
+ ) ;
126
82
127
83
// Sort by scores
128
84
let match_scores = matches
@@ -135,13 +91,13 @@ pub fn fuzzy(
135
91
} ;
136
92
let nearby_words_score = if opts. use_proximity {
137
93
nearby_words
138
- . get ( & haystack [ mtch. index_in_haystack ] . label )
94
+ . get ( & haystack_labels [ mtch. index_in_haystack ] )
139
95
. map ( |_| 2 )
140
96
. unwrap_or ( 0 )
141
97
} else {
142
98
0
143
99
} ;
144
- let score_offset = haystack[ mtch. index_in_haystack ] . score_offset . unwrap_or ( 0 ) ;
100
+ let score_offset = haystack[ mtch. index_in_haystack ] . score_offset ;
145
101
146
102
( mtch. score as i32 ) + frecency_score + nearby_words_score + score_offset
147
103
} )
0 commit comments