minimal extui fuzzy finder for neovim

feat: add `artio.mergesorters()`

+52 -4
+50 -3
lua/artio/init.lua
··· 16 16 config.set(cfg) 17 17 end 18 18 19 - ---@param lst artio.Picker.item[] 20 - ---@param input string 21 - ---@return artio.Picker.match[] 19 + ---@param a integer[] 20 + ---@param ... integer[] 21 + ---@return integer[] 22 + local function mergehl(a, ...) 23 + local hl_lists = { a, ... } 24 + 25 + local t = vim.iter(hl_lists):fold({}, function(hls, hl_list) 26 + for i = 1, #hl_list do 27 + hls[hl_list[i]] = true 28 + end 29 + return hls 30 + end) 31 + return vim.tbl_keys(t) 32 + end 33 + 34 + ---@param a artio.Picker.sorter 35 + ---@param ... artio.Picker.sorter 36 + ---@return artio.Picker.sorter 37 + function artio.mergesorters(a, ...) 38 + local sorters = { ... } ---@type artio.Picker.sorter[] 39 + 40 + return function(lst, input) 41 + local basematches = a(lst, input) 42 + 43 + return vim.iter(sorters):fold(basematches, function(oldmatches, sorter) 44 + ---@type artio.Picker.match[] 45 + local newmatches = sorter(lst, input) 46 + 47 + return vim.iter(newmatches):fold(oldmatches, function(matches, newmatch) 48 + local oldmatchidx 49 + for i = 1, #matches do 50 + if lst[matches[i][1]] == lst[newmatch[1]] then 51 + oldmatchidx = i 52 + break 53 + end 54 + end 55 + 56 + if oldmatchidx then 57 + local oldmatch = matches[oldmatchidx] 58 + matches[oldmatchidx] = { oldmatch[1], mergehl(oldmatch[2], newmatch[2]), oldmatch[3] + newmatch[3] } 59 + else 60 + matches[#matches + 1] = newmatch 61 + end 62 + return matches 63 + end) 64 + end) 65 + end 66 + end 67 + 68 + ---@type artio.Picker.sorter 22 69 artio.sorter = function(lst, input) 23 70 if not lst or #lst == 0 then 24 71 return {}
+2 -1
lua/artio/picker.lua
··· 2 2 3 3 ---@alias artio.Picker.item { id: integer, v: string, text: string, icon?: string, icon_hl?: string } 4 4 ---@alias artio.Picker.match [integer, integer[], integer] [item, pos[], score] 5 + ---@alias artio.Picker.sorter fun(lst: artio.Picker.item[], input: string): artio.Picker.match[] 5 6 6 7 ---@class artio.Picker.proto<T> 7 8 ---@field items? artio.Picker.item[] 8 - ---@field fn? fun(lst: artio.Picker.item[], input: string): artio.Picker.match[] 9 + ---@field fn? artio.Picker.sorter 9 10 ---@field on_close? fun(text: string, idx: integer) 10 11 ---@field format_item? fun(item: string): string 11 12 ---@field preview_item? fun(item: string): integer, fun(win: integer)