@@ -48,8 +48,8 @@ enum State<T> {
4848 Fuzzy {
4949 matcher : Matcher ,
5050 atom : Atom ,
51- /// Holds (haystack, item, score)
52- items : Vec < ( String , T , u16 ) > ,
51+ /// Holds (haystack, item, score, match_indices )
52+ items : Vec < ( String , T , u16 , Vec < usize > ) > ,
5353 } ,
5454}
5555
@@ -161,7 +161,13 @@ impl<T> NuMatcher<'_, T> {
161161 return false ;
162162 } ;
163163 if let Some ( item) = item {
164- items. push ( ( haystack. to_string ( ) , item, score) ) ;
164+ let indices = indices
165+ . iter ( )
166+ . map ( |i| {
167+ usize:: try_from ( * i) . expect ( "should be on at least a 32-bit system" )
168+ } )
169+ . collect ( ) ;
170+ items. push ( ( haystack. to_string ( ) , item, score, indices) ) ;
165171 }
166172 true
167173 }
@@ -180,10 +186,9 @@ impl<T> NuMatcher<'_, T> {
180186 self . matches_aux ( haystack, None )
181187 }
182188
183- /// Get all the items that matched (sorted)
184- pub fn results ( self ) -> Vec < T > {
185- match self . state {
186- State :: Prefix { mut items, .. } | State :: Substring { mut items, .. } => {
189+ fn sort ( & mut self ) {
190+ match & mut self . state {
191+ State :: Prefix { items, .. } | State :: Substring { items, .. } => {
187192 items. sort_by ( |( haystack1, _) , ( haystack2, _) | {
188193 let cmp_sensitive = haystack1. cmp ( haystack2) ;
189194 if self . options . case_sensitive {
@@ -195,26 +200,33 @@ impl<T> NuMatcher<'_, T> {
195200 . then ( cmp_sensitive)
196201 }
197202 } ) ;
198- items. into_iter ( ) . map ( |( _, item) | item) . collect :: < Vec < _ > > ( )
199203 }
200- State :: Fuzzy { mut items, .. } => {
201- match self . options . sort {
202- CompletionSort :: Alphabetical => {
203- items. sort_by ( |( haystack1, _, _) , ( haystack2, _, _) | {
204- haystack1. cmp ( haystack2)
205- } ) ;
206- }
207- CompletionSort :: Smart => {
208- items. sort_by ( |( haystack1, _, score1) , ( haystack2, _, score2) | {
209- score2. cmp ( score1) . then ( haystack1. cmp ( haystack2) )
210- } ) ;
211- }
204+ State :: Fuzzy { items, .. } => match self . options . sort {
205+ CompletionSort :: Alphabetical => {
206+ items. sort_by ( |( haystack1, _, _, _) , ( haystack2, _, _, _) | {
207+ haystack1. cmp ( haystack2)
208+ } ) ;
212209 }
213- items
214- . into_iter ( )
215- . map ( |( _, item, _) | item)
216- . collect :: < Vec < _ > > ( )
217- }
210+ CompletionSort :: Smart => {
211+ items. sort_by ( |( haystack1, _, score1, _) , ( haystack2, _, score2, _) | {
212+ score2. cmp ( score1) . then ( haystack1. cmp ( haystack2) )
213+ } ) ;
214+ }
215+ } ,
216+ }
217+ }
218+
219+ pub fn results ( mut self ) -> Vec < ( T , Option < Vec < usize > > ) > {
220+ self . sort ( ) ;
221+ match self . state {
222+ State :: Prefix { items, .. } | State :: Substring { items, .. } => items
223+ . into_iter ( )
224+ . map ( |( _, item) | ( item, None ) )
225+ . collect :: < Vec < _ > > ( ) ,
226+ State :: Fuzzy { items, .. } => items
227+ . into_iter ( )
228+ . map ( |( _, item, _, indices) | ( item, Some ( indices) ) )
229+ . collect :: < Vec < _ > > ( ) ,
218230 }
219231 }
220232}
@@ -224,6 +236,17 @@ impl NuMatcher<'_, SemanticSuggestion> {
224236 let value = sugg. suggestion . value . to_string ( ) ;
225237 self . add ( value, sugg)
226238 }
239+
240+ /// Get all the items that matched (sorted)
241+ pub fn suggestion_results ( self ) -> Vec < SemanticSuggestion > {
242+ self . results ( )
243+ . into_iter ( )
244+ . map ( |( mut sugg, indices) | {
245+ sugg. suggestion . match_indices = indices;
246+ sugg
247+ } )
248+ . collect ( )
249+ }
227250}
228251
229252impl From < CompletionAlgorithm > for MatchAlgorithm {
@@ -311,10 +334,11 @@ mod test {
311334 } ;
312335 let mut matcher = NuMatcher :: new ( needle, & options) ;
313336 matcher. add ( haystack, haystack) ;
337+ let results: Vec < _ > = matcher. results ( ) . iter ( ) . map ( |r| r. 0 ) . collect ( ) ;
314338 if should_match {
315- assert_eq ! ( vec![ haystack] , matcher . results( ) ) ;
339+ assert_eq ! ( vec![ haystack] , results) ;
316340 } else {
317- assert_ne ! ( vec![ haystack] , matcher . results( ) ) ;
341+ assert_ne ! ( vec![ haystack] , results) ;
318342 }
319343 }
320344
@@ -329,7 +353,14 @@ mod test {
329353 matcher. add ( item, item) ;
330354 }
331355 // Sort by score, then in alphabetical order
332- assert_eq ! ( vec![ "fob" , "foo bar" , "foo/bar" ] , matcher. results( ) ) ;
356+ assert_eq ! (
357+ vec![
358+ ( "fob" , Some ( vec![ 0 , 1 , 2 ] ) ) ,
359+ ( "foo bar" , Some ( vec![ 0 , 1 , 4 ] ) ) ,
360+ ( "foo/bar" , Some ( vec![ 0 , 1 , 4 ] ) )
361+ ] ,
362+ matcher. results( )
363+ ) ;
333364 }
334365
335366 #[ test]
@@ -347,6 +378,12 @@ mod test {
347378 matcher. add ( item, item) ;
348379 }
349380 // Make sure the spaces are respected
350- assert_eq ! ( vec![ "'i love spaces' so much" ] , matcher. results( ) ) ;
381+ assert_eq ! (
382+ vec![ (
383+ "'i love spaces' so much" ,
384+ Some ( vec![ 0 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] )
385+ ) ] ,
386+ matcher. results( )
387+ ) ;
351388 }
352389}
0 commit comments