feat(views): make queue view sort order configurable (#154)
Problem: the queue/priority view sort in `sort_tasks_priority()` uses a hardcoded tiebreak chain (status, priority, due, order, id). Users who care more about due dates than priority have no way to reorder it. Solution: add `view.queue.sort` config field (string[]) that defines an ordered tiebreak chain. `build_queue_comparator()` maps each key to a comparison function and returns a single comparator. Unknown keys emit a `log.warn`. The default matches the previous hardcoded behavior.
This commit is contained in:
parent
283f93eda1
commit
969dbd299f
4 changed files with 169 additions and 12 deletions
|
|
@ -87,6 +87,7 @@
|
|||
---@field hide_done_categories? boolean
|
||||
|
||||
---@class pending.QueueViewConfig
|
||||
---@field sort? string[]
|
||||
|
||||
---@class pending.ViewConfig
|
||||
---@field default? 'category'|'priority'
|
||||
|
|
@ -133,7 +134,9 @@ local defaults = {
|
|||
folding = true,
|
||||
hide_done_categories = false,
|
||||
},
|
||||
queue = {},
|
||||
queue = {
|
||||
sort = { 'status', 'priority', 'due', 'order', 'id' },
|
||||
},
|
||||
},
|
||||
keymaps = {
|
||||
close = 'q',
|
||||
|
|
|
|||
|
|
@ -106,17 +106,23 @@ local function sort_tasks(tasks)
|
|||
end)
|
||||
end
|
||||
|
||||
---@param tasks pending.Task[]
|
||||
local function sort_tasks_priority(tasks)
|
||||
table.sort(tasks, function(a, b)
|
||||
---@type table<string, fun(a: pending.Task, b: pending.Task): boolean?>
|
||||
local sort_key_comparators = {
|
||||
status = function(a, b)
|
||||
local ra = status_rank[a.status] or 1
|
||||
local rb = status_rank[b.status] or 1
|
||||
if ra ~= rb then
|
||||
return ra < rb
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
priority = function(a, b)
|
||||
if a.priority ~= b.priority then
|
||||
return a.priority > b.priority
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
due = function(a, b)
|
||||
local a_due = a.due or ''
|
||||
local b_due = b.due or ''
|
||||
if a_due ~= b_due then
|
||||
|
|
@ -128,11 +134,56 @@ local function sort_tasks_priority(tasks)
|
|||
end
|
||||
return a_due < b_due
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
order = function(a, b)
|
||||
if a.order ~= b.order then
|
||||
return a.order < b.order
|
||||
end
|
||||
return a.id < b.id
|
||||
end)
|
||||
return nil
|
||||
end,
|
||||
id = function(a, b)
|
||||
if a.id ~= b.id then
|
||||
return a.id < b.id
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
age = function(a, b)
|
||||
if a.id ~= b.id then
|
||||
return a.id < b.id
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
}
|
||||
|
||||
---@return fun(a: pending.Task, b: pending.Task): boolean
|
||||
local function build_queue_comparator()
|
||||
local log = require('pending.log')
|
||||
local keys = config.get().view.queue.sort or { 'status', 'priority', 'due', 'order', 'id' }
|
||||
local comparators = {}
|
||||
for _, key in ipairs(keys) do
|
||||
local cmp = sort_key_comparators[key]
|
||||
if cmp then
|
||||
table.insert(comparators, cmp)
|
||||
else
|
||||
log.warn('unknown queue sort key: ' .. key)
|
||||
end
|
||||
end
|
||||
return function(a, b)
|
||||
for _, cmp in ipairs(comparators) do
|
||||
local result = cmp(a, b)
|
||||
if result ~= nil then
|
||||
return result
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---@param tasks pending.Task[]
|
||||
local function sort_tasks_priority(tasks)
|
||||
local cmp = build_queue_comparator()
|
||||
table.sort(tasks, cmp)
|
||||
end
|
||||
|
||||
---@param tasks pending.Task[]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue