1+ use std:: cell:: RefCell ;
12use std:: cmp:: Reverse ;
23use std:: ops:: Deref ;
34use std:: rc:: Rc ;
45
56use gpui:: { App , Global , Resource , SharedString } ;
7+ use nucleo_matcher:: pattern:: { AtomKind , CaseMatching , Normalization , Pattern } ;
8+ use nucleo_matcher:: { Matcher , Utf32Str } ;
69
710use crate :: config:: Config ;
811use crate :: entries:: application:: Application ;
@@ -41,6 +44,12 @@ impl Entry {
4144 }
4245 }
4346
47+ pub fn searchable ( & self ) -> Utf32Str < ' _ > {
48+ match self {
49+ Entry :: Application ( entry) => entry. searchable . slice ( ..) ,
50+ }
51+ }
52+
4453 pub fn open ( & self , cx : & mut App ) -> bool {
4554 cx. global_mut :: < SearchEntries > ( )
4655 . increment_frequency ( self . id ( ) ) ;
@@ -55,6 +64,7 @@ impl Entry {
5564pub struct SearchEntries {
5665 entries : Vec < Entry > ,
5766 frequencies : Frequencies ,
67+ matcher : RefCell < Matcher > ,
5868}
5969
6070impl SearchEntries {
@@ -68,6 +78,7 @@ impl SearchEntries {
6878 Self {
6979 entries,
7080 frequencies : Frequencies :: load ( ) ,
81+ matcher : RefCell :: new ( Matcher :: default ( ) ) ,
7182 }
7283 }
7384
@@ -82,18 +93,32 @@ impl SearchEntries {
8293 }
8394
8495 pub fn filtered ( & self , search_term : & str ) -> Vec < Entry > {
85- if search_term. trim ( ) . is_empty ( ) {
96+ let search_term = search_term. trim ( ) ;
97+ if search_term. is_empty ( ) {
8698 return self . entries . clone ( ) ;
8799 }
88100
89- self . entries
101+ let p = Pattern :: new (
102+ search_term,
103+ CaseMatching :: Ignore ,
104+ Normalization :: Smart ,
105+ AtomKind :: Fuzzy ,
106+ ) ;
107+
108+ let mut matcher = self . matcher . borrow_mut ( ) ;
109+ let mut result: Vec < _ > = self
110+ . entries
90111 . iter ( )
91- . filter ( |entry| {
92- entry. name ( ) . to_lowercase ( ) . contains ( search_term)
93- || entry
94- . description ( )
95- . is_some_and ( |desc| desc. to_lowercase ( ) . contains ( search_term) )
112+ . filter_map ( |item| {
113+ p. score ( item. searchable ( ) , & mut matcher)
114+ . map ( |score| ( item, score) )
96115 } )
116+ . collect ( ) ;
117+ result. sort_by_key ( |( _, score) | Reverse ( * score) ) ;
118+
119+ result
120+ . into_iter ( )
121+ . map ( |( entry, _) | entry)
97122 . cloned ( )
98123 . collect ( )
99124 }
0 commit comments