feat(picker.sort): default sorter can now sort by len of a field

This commit is contained in:
Folke Lemaitre 2025-01-17 09:40:38 +01:00
parent 71f69e5e57
commit 6ae87d9f62
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040

View file

@ -1,7 +1,7 @@
---@class snacks.picker.sorters
local M = {}
---@alias snacks.picker.sort.Field { name: string, desc: boolean }
---@alias snacks.picker.sort.Field { name: string, desc: boolean, len?: boolean }
---@class snacks.picker.sort.Config
---@field fields? (snacks.picker.sort.Field|string)[]
@ -11,7 +11,16 @@ 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
table.insert(fields, { name = f, desc = false })
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
@ -22,11 +31,16 @@ function M.default(opts)
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) and (av ~= bv) then
if field.desc then
return av > bv
else
return av < bv
if av ~= nil and bv ~= nil then
if field.len then
av, bv = #av, #bv
end
if av ~= bv then
if field.desc then
return av > bv
else
return av < bv
end
end
end
end