Skip to content

Commit 470a98c

Browse files
authored
fix: massively improve annotations, optimized code portions (#16)
* fix: massively improve annotations, optimized code portions * fix(windows): improve annotations * fix: update annotation * fix: use `string.<function>()` instead Signed-off-by: Guennadi Maximov C <g.maxc.fox@protonmail.com>
1 parent 0466fd4 commit 470a98c

41 files changed

Lines changed: 914 additions & 702 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lua/picker/config.lua

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
---@class Picker.Config
12
local M = {}
23

3-
---@type PickerConfig
4-
local default = {
4+
local default = { ---@type PickerConfig
55
filter = {
66
ignorecase = false,
77
matcher = 'fzy',
@@ -38,12 +38,13 @@ local default = {
3838
},
3939
}
4040

41+
---@param opt? PickerConfig
4142
function M.setup(opt)
42-
default = vim.tbl_deep_extend('force', default, opt)
43+
default = vim.tbl_deep_extend('force', default, opt or {})
4344
end
4445

46+
---@return PickerConfig default
4547
function M.get()
4648
return default
4749
end
48-
4950
return M

lua/picker/filter.lua

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
---@class Picker.Filter
12
local M = {}
23

34
---@param input string
@@ -10,7 +11,7 @@ function M.filter(input, source, ignorecase)
1011
if not ok then
1112
matcher = require('picker.matchers.fzy')
1213
end
13-
if #input == 0 then
14+
if input == '' then
1415
local i = 1
1516
source.filter_items = vim.tbl_map(function(t)
1617
i = i + 1
@@ -19,14 +20,14 @@ function M.filter(input, source, ignorecase)
1920
else
2021
if
2122
source.state.previous_input
22-
and #source.state.previous_input > 0
23+
and string.len(source.state.previous_input) > 0
2324
and matcher.has_match(source.state.previous_input, input, ignorecase)
2425
then
2526
local rst = {}
26-
for _, v in ipairs(source.filter_items) do
27+
for i, v in ipairs(source.filter_items) do
2728
if matcher.has_match(input, v[4].str, ignorecase) then
2829
local p, s = matcher.positions(input, v[4].str, ignorecase)
29-
table.insert(rst, { _, p, s, v[4] })
30+
table.insert(rst, { i, p, s, v[4] })
3031
end
3132
end
3233
if source.state.filter_count < #source.state.items then
@@ -36,7 +37,7 @@ function M.filter(input, source, ignorecase)
3637
then
3738
local p, s =
3839
matcher.positions(input, source.state.items[i].str, ignorecase)
39-
table.insert(rst, { _, p, s, source.state.items[i] })
40+
table.insert(rst, { i, p, s, source.state.items[i] })
4041
end
4142
end
4243
end
@@ -49,7 +50,7 @@ function M.filter(input, source, ignorecase)
4950
then
5051
local p, s =
5152
matcher.positions(input, source.state.items[i].str, ignorecase)
52-
table.insert(rst, { _, p, s, source.state.items[i] })
53+
table.insert(rst, { i, p, s, source.state.items[i] })
5354
end
5455
end
5556
source.filter_items = rst
@@ -61,5 +62,4 @@ function M.filter(input, source, ignorecase)
6162
source.state.previous_input = input
6263
source.state.filter_count = #source.state.items
6364
end
64-
6565
return M

lua/picker/init.lua

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
1+
---@class Picker
12
local M = {}
23

34
local util = require('picker.util')
45

6+
---@param argv string[]
7+
---@param opt? table
58
function M.open(argv, opt)
6-
util.info('argv is:' .. vim.inspect(argv))
7-
if #argv == 0 then
9+
util.info('argv is: ' .. vim.inspect(argv))
10+
if vim.tbl_isempty(argv) then
811
require('picker.windows').open(require('picker.sources'))
912
return
1013
end
1114
local ok, source = pcall(require, 'picker.sources.' .. argv[1])
1215
if not ok then
1316
util.notify(
14-
string.format('can not found source "%s" for picker.nvim', argv[1])
17+
string.format('Unable to find source "%s" for picker.nvim', argv[1])
1518
)
16-
else
17-
if not source.enabled then
18-
source.name = source.name or argv[1]
19-
require('picker.windows').open(source, opt)
20-
elseif source.enabled and source.enabled() then
21-
source.name = source.name or argv[1]
22-
require('picker.windows').open(source, opt)
23-
end
19+
return
20+
end
21+
22+
if source.enabled and not (source.enabled and source.enabled()) then
23+
return
2424
end
25+
source.name = source.name or argv[1]
26+
require('picker.windows').open(source, opt)
2527
end
2628

29+
---@param opt? PickerConfig
2730
function M.setup(opt)
28-
require('picker.config').setup(opt)
31+
require('picker.config').setup(opt or {})
2932
end
3033

3134
return M

lua/picker/layout/default.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
---@class Picker.Layout
12
local M = {}
23

34
---@type PickerLayout
@@ -14,6 +15,8 @@ local winhighlight =
1415
'NormalFloat:Normal,FloatBorder:WinSeparator,Search:None,CurSearch:None'
1516
local extns = vim.api.nvim_create_namespace('picker.nvim')
1617

18+
---@param source PickerSourceConfig
19+
---@param config PickerConfig
1720
---@return PickerLayout
1821
function M.render_windows(source, config)
1922
-- 窗口位置
@@ -266,7 +269,6 @@ function M.render_windows(source, config)
266269
end
267270
if not vim.api.nvim_win_is_valid(layout.list_win) then
268271
layout.list_win = vim.api.nvim_open_win(layout.list_buf, false, {
269-
270272
relative = 'editor',
271273
width = screen_width,
272274
height = screen_height - 5,
@@ -277,7 +279,6 @@ function M.render_windows(source, config)
277279
})
278280
else
279281
vim.api.nvim_win_set_config(layout.list_win, {
280-
281282
relative = 'editor',
282283
width = screen_width,
283284
height = screen_height - 5,

lua/picker/matchers/fzy.lua

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ local SCORE_MAX = math.huge
1515
local SCORE_MIN = -math.huge
1616
local MATCH_MAX_LENGTH = 1024
1717

18+
---@class Pickers.Matchers.Fzy
1819
local 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
3136
function 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
4852
end
4953

54+
---@param c string
5055
local function is_lower(c)
51-
return c:match('%l')
56+
return string.match(c, '%l')
5257
end
5358

59+
---@param c string
5460
local function is_upper(c)
55-
return c:match('%u')
61+
return string.match(c, '%u')
5662
end
5763

64+
---@param haystack string
65+
---@return table<integer, number> match_bonus
5866
local 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
8087
end
8188

89+
---@param needle string
90+
---@param haystack string
91+
---@param D number[][]
92+
---@param M number[][]
93+
---@param case_sensitive? boolean
8294
local 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
142158
function 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]
156171
end
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
173193
function 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

@@ -221,9 +240,13 @@ end
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 }[]
224247
function 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
244268
function fzy.get_score_min()
245269
return SCORE_MIN
246270
end
247271

248272
-- The score returned for exact matches. This is the highest possible score.
273+
---@return number SCORE_MAX
249274
function fzy.get_score_max()
250275
return SCORE_MAX
251276
end
252277

253278
-- The maximum size for which `fzy` will evaluate scores.
279+
---@return integer MATCH_MAX_LENGTH
254280
function fzy.get_max_length()
255281
return MATCH_MAX_LENGTH
256282
end
@@ -259,6 +285,7 @@ end
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
262289
function fzy.get_score_floor()
263290
return MATCH_MAX_LENGTH * SCORE_GAP_INNER
264291
end
@@ -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
270298
function fzy.get_score_ceiling()
271299
return MATCH_MAX_LENGTH * SCORE_MATCH_CONSECUTIVE
272300
end
273301

274302
-- The name of the currently-running implmenetation, "lua" or "native".
303+
---@return 'lua'|'native' implementation
275304
function fzy.get_implementation_name()
276305
return 'lua'
277306
end

0 commit comments

Comments
 (0)