feat: add <C-a> / <C-x> keymaps for priority increment/decrement (#114)

* feat(s3): create bucket interactively during auth when unconfigured

Problem: when a user runs `:Pending s3 auth` with no bucket configured,
auth succeeds but offers no way to create the bucket. The user must
manually run `aws s3api create-bucket` and update their config.

Solution: add `util.input()` coroutine-aware prompt wrapper and a
`create_bucket()` flow in `s3.lua` that prompts for bucket name and
region, handles the `us-east-1` LocationConstraint quirk, and logs a
config snippet on success. Called automatically from `auth()` when
`sync.s3.bucket` is absent.

* ci: typing

* feat(parse): add `parse_duration_to_days` for duration string conversion

Problem: The archive command accepted only a bare integer for days,
inconsistent with the `+Nd`/`+Nw`/`+Nm` duration syntax used elsewhere.

Solution: Add `parse_duration_to_days()` supporting `Nd`, `Nw`, `Nm`,
and bare integers. Returns nil on invalid input for caller error handling.

* feat(archive): duration syntax and confirmation prompt

Problem: `:Pending archive` accepted only a bare integer for days and
silently deleted tasks with no confirmation, risking accidental data loss.

Solution: Accept duration strings (`7d`, `3w`, `2m`) via
`parse.parse_duration_to_days()`, show a `vim.ui.input` confirmation
prompt before removing tasks, and skip the prompt when zero tasks match.

* feat: add `<C-a>` / `<C-x>` keymaps for priority increment/decrement

Problem: Priority could only be cycled with `g!` (0→1→2→3→0), with no
way to directly increment or decrement.

Solution: Add `adjust_priority()` with clamping at 0 and `max_priority`,
exposed as `increment_priority()` / `decrement_priority()` on `<C-a>` /
`<C-x>`. Includes `<Plug>` mappings and vimdoc.

* fix(s3): use parenthetical defaults in bucket creation prompts

Problem: `util.input` with `default` pre-filled the input field, and
the success message said "Add to your config" ambiguously.

Solution: Show defaults in prompt text as `(default)` instead of
pre-filling, and clarify the message to "Add to your pending.nvim
config".

* ci: format
This commit is contained in:
Barrett Ruth 2026-03-08 20:49:05 -04:00
parent aa63b9bd6c
commit 6b23e6810e
7 changed files with 106 additions and 15 deletions

View file

@ -363,6 +363,12 @@ function M._setup_buf_mappings(bufnr)
blocked = function()
M.toggle_status('blocked')
end,
priority_up = function()
M.increment_priority()
end,
priority_down = function()
M.decrement_priority()
end,
undo = function()
M.undo_write()
end,
@ -646,6 +652,56 @@ function M.toggle_priority()
end
end
---@param delta integer
---@return nil
local function adjust_priority(delta)
local bufnr = buffer.bufnr()
if not bufnr then
return
end
if not require_saved() then
return
end
local row = vim.api.nvim_win_get_cursor(0)[1]
local meta = buffer.meta()
if not meta[row] or meta[row].type ~= 'task' then
return
end
local id = meta[row].id
if not id then
return
end
local s = get_store()
local task = s:get(id)
if not task then
return
end
local max = require('pending.config').get().max_priority or 3
local new_priority = math.max(0, math.min(max, task.priority + delta))
if new_priority == task.priority then
return
end
s:update(id, { priority = new_priority })
_save_and_notify()
buffer.render(bufnr)
for lnum, m in ipairs(buffer.meta()) do
if m.id == id then
vim.api.nvim_win_set_cursor(0, { lnum, 0 })
break
end
end
end
---@return nil
function M.increment_priority()
adjust_priority(1)
end
---@return nil
function M.decrement_priority()
adjust_priority(-1)
end
---@return nil
function M.prompt_date()
local bufnr = buffer.bufnr()
@ -1032,7 +1088,13 @@ function M.archive(arg)
return
end
confirm(
'Archive ' .. count .. ' task' .. (count == 1 and '' or 's') .. ' completed/deleted more than ' .. days .. 'd ago?',
'Archive '
.. count
.. ' task'
.. (count == 1 and '' or 's')
.. ' completed/deleted more than '
.. days
.. 'd ago?',
function()
local kept = {}
for _, task in ipairs(tasks) do