@@ -15,6 +15,7 @@ local SCORE_MAX = math.huge
1515local SCORE_MIN = - math.huge
1616local MATCH_MAX_LENGTH = 1024
1717
18+ --- @class Pickers.Matchers.Fzy
1819local fzy = {}
1920
2021-- Check if `needle` is a subsequence of the `haystack`.
@@ -28,6 +29,10 @@ local fzy = {}
2829--
2930-- Returns:
3031-- bool
32+ --- @param needle string
33+ --- @param haystack string
34+ --- @param case_sensitive ? boolean
35+ --- @return boolean match
3136function fzy .has_match (needle , haystack , case_sensitive )
3237 if not case_sensitive then
3338 needle = string.lower (needle )
@@ -36,31 +41,33 @@ function fzy.has_match(needle, haystack, case_sensitive)
3641
3742 local j = 1
3843 for i = 1 , string.len (needle ) do
39- j = string.find (haystack , needle : sub (i , i ), j , true )
44+ j = string.find (haystack , string. sub (needle , i , i ), j , true )
4045 if not j then
4146 return false
42- else
43- j = j + 1
4447 end
48+ j = j + 1
4549 end
4650
4751 return true
4852end
4953
54+ --- @param c string
5055local function is_lower (c )
51- return c : match (' %l' )
56+ return string. match (c , ' %l' )
5257end
5358
59+ --- @param c string
5460local function is_upper (c )
55- return c : match (' %u' )
61+ return string. match (c , ' %u' )
5662end
5763
64+ --- @param haystack string
65+ --- @return table<integer , number> match_bonus
5866local function precompute_bonus (haystack )
59- local match_bonus = {}
60-
67+ local match_bonus = {} --- @type table<integer , number>
6168 local last_char = ' /'
6269 for i = 1 , string.len (haystack ) do
63- local this_char = haystack : sub (i , i )
70+ local this_char = string. sub (haystack , i , i )
6471 if last_char == ' /' or last_char == ' \\ ' then
6572 match_bonus [i ] = SCORE_MATCH_SLASH
6673 elseif last_char == ' -' or last_char == ' _' or last_char == ' ' then
@@ -79,6 +86,11 @@ local function precompute_bonus(haystack)
7986 return match_bonus
8087end
8188
89+ --- @param needle string
90+ --- @param haystack string
91+ --- @param D number[][]
92+ --- @param M number[][]
93+ --- @param case_sensitive ? boolean
8294local function compute (needle , haystack , D , M , case_sensitive )
8395 -- Note that the match bonuses must be computed before the arguments are
8496 -- converted to lowercase, since there are bonuses for camelCase.
@@ -95,7 +107,7 @@ local function compute(needle, haystack, D, M, case_sensitive)
95107 -- get all the characters from the haystack once now, to reuse below.
96108 local haystack_chars = {}
97109 for i = 1 , m do
98- haystack_chars [i ] = haystack : sub (i , i )
110+ haystack_chars [i ] = string. sub (haystack , i , i )
99111 end
100112
101113 for i = 1 , n do
@@ -104,7 +116,7 @@ local function compute(needle, haystack, D, M, case_sensitive)
104116
105117 local prev_score = SCORE_MIN
106118 local gap_score = i == n and SCORE_GAP_TRAILING or SCORE_GAP_INNER
107- local needle_char = needle : sub (i , i )
119+ local needle_char = string. sub (needle , i , i )
108120
109121 for j = 1 , m do
110122 if needle_char == haystack_chars [j ] then
@@ -139,20 +151,23 @@ end
139151-- Returns:
140152-- number: higher scores indicate better matches. See also `get_score_min`
141153-- and `get_score_max`.
154+ --- @param needle string
155+ --- @param haystack string
156+ --- @param case_sensitive ? boolean
157+ --- @return number score
142158function fzy .score (needle , haystack , case_sensitive )
143- local n = string.len (needle )
144- local m = string.len (haystack )
159+ local n , m = string.len (needle ), string.len (haystack )
145160
146161 if n == 0 or m == 0 or m > MATCH_MAX_LENGTH or n > m then
147162 return SCORE_MIN
148- elseif n == m then
163+ end
164+ if n == m then
149165 return SCORE_MAX
150- else
151- local D = {}
152- local M = {}
153- compute (needle , haystack , D , M , case_sensitive )
154- return M [n ][m ]
155166 end
167+
168+ local D , M = {}, {} --- @type number[][] , number[][]
169+ compute (needle , haystack , D , M , case_sensitive )
170+ return M [n ][m ]
156171end
157172
158173-- Compute the locations where fzy matches a string.
@@ -170,39 +185,43 @@ end
170185-- {int,...}: indices, where `indices[n]` is the location of the `n`th
171186-- character of `needle` in `haystack`.
172187-- number: the same matching score returned by `score`
188+ --- @param needle string
189+ --- @param haystack string
190+ --- @param case_sensitive ? boolean
191+ --- @return table<integer , integer> positions
192+ --- @return number score
173193function fzy .positions (needle , haystack , case_sensitive )
174- local n = string.len (needle )
175- local m = string.len (haystack )
194+ local n , m = string.len (needle ), string.len (haystack )
176195
177196 if n == 0 or m == 0 or m > MATCH_MAX_LENGTH or n > m then
178197 return {}, SCORE_MIN
179- elseif n == m then
198+ end
199+ if n == m then
180200 local consecutive = {}
181201 for i = 1 , n do
182202 consecutive [i ] = i
183203 end
184204 return consecutive , SCORE_MAX
185205 end
186206
187- local D = {}
188- local M = {}
207+ local D , M = {}, {} --- @type number[][] , number[][]
189208 compute (needle , haystack , D , M , case_sensitive )
190209
191- local positions = {}
210+ local positions = {} --- @type table<integer , integer>
192211 local match_required = false
193212 local j = m
194213 for i = n , 1 , - 1 do
195214 while j >= 1 do
196215 if D [i ][j ] ~= SCORE_MIN and (match_required or D [i ][j ] == M [i ][j ]) then
197- match_required = ( i ~= 1 )
216+ match_required = i ~= 1
198217 and (j ~= 1 )
199218 and (M [i ][j ] == D [i - 1 ][j - 1 ] + SCORE_MATCH_CONSECUTIVE )
200219 positions [i ] = j
201220 j = j - 1
202221 break
203- else
204- j = j - 1
205222 end
223+
224+ j = j - 1
206225 end
207226 end
208227
221240-- in `haystacks`, each entry giving the index of the line in `haystacks`
222241-- as well as the equivalent to the return value of `positions` for that
223242-- line.
243+ --- @param needle string
244+ --- @param haystacks string[]
245+ --- @param case_sensitive ? boolean
246+ --- @return { [1] : integer , [2] : table<integer , integer> , [3] : number , [4] : string } []
224247function fzy .filter (needle , haystacks , case_sensitive )
248+ --- @type { [1] : integer , [2] : table<integer , integer> , [3] : number , [4] : string } []
225249 local result = {}
226-
227250 for i , line in ipairs (haystacks ) do
228251 if fzy .has_match (needle , line , case_sensitive ) then
229252 local p , s = fzy .positions (needle , line , case_sensitive )
@@ -241,16 +264,19 @@ end
241264-- - a `needle` or `haystack` larger than than `get_max_length`,
242265-- the `score` function will return this exact value, which can be used as a
243266-- sentinel. This is the lowest possible score.
267+ --- @return number SCORE_MIN
244268function fzy .get_score_min ()
245269 return SCORE_MIN
246270end
247271
248272-- The score returned for exact matches. This is the highest possible score.
273+ --- @return number SCORE_MAX
249274function fzy .get_score_max ()
250275 return SCORE_MAX
251276end
252277
253278-- The maximum size for which `fzy` will evaluate scores.
279+ --- @return integer MATCH_MAX_LENGTH
254280function fzy .get_max_length ()
255281 return MATCH_MAX_LENGTH
256282end
259285--
260286-- For matches that don't return `get_score_min`, their score will be greater
261287-- than than this value.
288+ --- @return number floor
262289function fzy .get_score_floor ()
263290 return MATCH_MAX_LENGTH * SCORE_GAP_INNER
264291end
@@ -267,11 +294,13 @@ end
267294--
268295-- For matches that don't return `get_score_max`, their score will be less than
269296-- this value.
297+ --- @return number ceiling
270298function fzy .get_score_ceiling ()
271299 return MATCH_MAX_LENGTH * SCORE_MATCH_CONSECUTIVE
272300end
273301
274302-- The name of the currently-running implmenetation, "lua" or "native".
303+ --- @return ' lua' | ' native' implementation
275304function fzy .get_implementation_name ()
276305 return ' lua'
277306end
0 commit comments