snacks.nvim/lua/snacks/picker/sort.lua
2025-02-11 13:41:32 +01:00

62 lines
1.5 KiB
Lua

---@class snacks.picker.sorters
local M = {}
---@alias snacks.picker.sort.Field { name: string, desc: boolean, len?: boolean }
---@class snacks.picker.sort.Config
---@field fields? (snacks.picker.sort.Field|string)[]
---@param opts? snacks.picker.sort.Config
function M.default(opts)
local fields = {} ---@type snacks.picker.sort.Field[]
for _, f in ipairs(opts and opts.fields or { { name = "score", desc = true }, "idx" }) do
if type(f) == "string" then
local desc, len = false, nil
if f:sub(1, 1) == "#" then
f, len = f:sub(2), true
end
if f:sub(-5) == ":desc" then
f, desc = f:sub(1, -6), true
elseif f:sub(-4) == ":asc" then
f = f:sub(1, -5)
end
table.insert(fields, { name = f, desc = desc, len = len })
else
table.insert(fields, f)
end
end
---@param a snacks.picker.Item
---@param b snacks.picker.Item
return function(a, b)
for _, field in ipairs(fields) do
local av, bv = a[field.name], b[field.name]
if av ~= nil and bv ~= nil then
if field.len then
av, bv = #av, #bv
end
if av ~= bv then
if type(av) == "boolean" then
av, bv = av and 0 or 1, bv and 0 or 1
end
if field.desc then
return av > bv
else
return av < bv
end
end
end
end
return false
end
end
function M.idx()
---@param a snacks.picker.Item
---@param b snacks.picker.Item
return function(a, b)
return a.idx < b.idx
end
end
return M