mirror of
https://github.com/folke/snacks.nvim
synced 2025-07-07 21:25:11 +00:00
62 lines
1.5 KiB
Lua
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
|