1313
1414import rich .repr
1515
16+ from textual .cache import LRUCache
1617from textual .content import Content
1718from textual .visual import Style
1819
@@ -57,13 +58,16 @@ class FuzzySearch:
5758 Unlike a regex solution, this will finds all possible matches.
5859 """
5960
61+ cache : LRUCache [tuple [str , str , bool ], tuple [float , tuple [int , ...]]] = LRUCache (
62+ maxsize = 1024
63+ )
64+
6065 def __init__ (self , case_sensitive : bool = False ) -> None :
6166 """Initialize fuzzy search.
6267
6368 Args:
6469 case_sensitive: Is the match case sensitive?
6570 """
66- self .cache : dict [tuple [str , str , bool ], tuple [float , tuple [int , ...]]] = {}
6771 self .case_sensitive = case_sensitive
6872
6973 def match (self , query : str , candidate : str ) -> tuple [float , tuple [int , ...]]:
@@ -124,8 +128,8 @@ def score(search: _Search) -> float:
124128 """
125129 # This is a heuristic, and can be tweaked for better results
126130 # Boost first letter matches
127- score : float = sum (
128- ( 2.0 if offset in first_letters else 1.0 ) for offset in search .offsets
131+ score : float = len ( search . offsets ) + len (
132+ first_letters . intersection ( search .offsets )
129133 )
130134 # Boost to favor less groups
131135 offset_count = len (search .offsets )
@@ -140,7 +144,7 @@ def score(search: _Search) -> float:
140144 find = candidate .find
141145 # Limit the number of loops out of an abundance of caution.
142146 # This would be hard to reach without contrived data.
143- remaining_loops = 200
147+ remaining_loops = 10_000
144148
145149 while stack and (remaining_loops := remaining_loops - 1 ):
146150 search = pop ()
0 commit comments