Problem: several critical code paths had zero test coverage —
parse.resolve_date (relative date resolution), store.snapshot
(foundation of the undo stack), and the diff.apply invariant that
unchanged tasks do not get their modified timestamp bumped. The
diff.apply due/priority clearing paths were also untested.
Solution: add six targeted test blocks across parse_spec, store_spec,
and diff_spec: resolve_date happy/failure paths, parse.body with
relative due tokens, snapshot copy-semantics and deleted-task
exclusion, diff unchanged-modified invariant, due cleared on removal,
priority cleared on ! removal.
* feat(config): add category_order field
Problem: category display order was always insertion order with no way
to configure it.
Solution: add category_order to config defaults so users can declare a
preferred category ordering; unspecified categories append after.
* feat(parse): add relative date resolution
Problem: due dates required full YYYY-MM-DD input, adding friction for
common cases like "today" or "next monday".
Solution: add resolve_date() supporting today, tomorrow, +Nd, and
weekday abbreviations; extend inline token parsing to resolve relative
values before falling back to strict date validation.
* feat(views): overdue flag, category in priority view, category ordering
Problem: overdue tasks were visually indistinct from upcoming ones;
priority view had no category context; category display order was not
configurable.
Solution: compute overdue meta flag for pending tasks past their due
date; set show_category on priority view task meta; reorder categories
according to config.category_order when present.
* feat(buffer): overdue highlight, category virt text in priority view
Problem: overdue tasks had no visual distinction; priority view showed
no category context alongside due dates.
Solution: add PendingOverdue highlight group; render category name as
right-aligned virtual text in priority view, composited with the due
date when both are present.
* feat(init): undo write and buffer-local default mappings
Problem: _undo_state was captured on every save but never consumed;
toggle_priority and prompt_date had no buffer-local defaults, requiring
manual <Plug> configuration.
Solution: implement undo_write() to restore pre-save task state; add !,
d, and U as buffer-local defaults following fugitive's philosophy of
owning the buffer; expose :Pending undo as a command alias.
* test(views): add views spec
Problem: views.lua had no test coverage.
Solution: add 26 tests covering category_view and priority_view
including sort order, line format, overdue detection, show_category
meta, and category_order config behavior.
* test(archive): add archive spec
Problem: archive had no test coverage.
Solution: add 9 tests covering cutoff logic, custom day counts, pending
task preservation, deleted task cleanup, and notify output.
* docs: add vimdoc
Problem: no :help documentation existed.
Solution: add doc/pending.txt covering all features — commands,
mappings, views, configuration, Google Calendar sync, highlight groups,
data format, and health check — following standard vimdoc conventions.
* ci: format
* fix: resolve lint and type check errors
Problem: selene flagged unused variables in new spec files; LuaLS
flagged os.date/os.time return type mismatches, integer? assignments,
and stale task.Task/task.GcalConfig type references.
Solution: prefix unused spec variables with _ or drop unnecessary
assignments; add --[[@as string/integer]] casts for os.date and
os.time calls; add category_order field to pending.Config annotation;
fix task.GcalConfig -> pending.GcalConfig and task.Task[] ->
pending.Task[]; add nil guards on meta[row].id before store calls;
cast store.data() return to non-optional.
* ci: format
* fix: sync
* ci: format
Problem: unused variables (undo_state, sha_result, date match
captures) and duplicate if/else branches in gcal sync triggered
selene warnings and errors.
Solution: prefix unused state with underscore, simplify date
validation to a single pattern match, remove dead sha_result
call, and merge duplicate event deletion branches into a single
condition.
Problem: parse_buffer classified /id/-prefixed task lines as headers
because '/' matches the '^%S' header pattern. Store timestamp test
was flaky when add and update ran within the same second.
Solution: check for task line patterns (id prefix or 2-space indent)
before falling through to the header branch. Backdate the initial
modified timestamp in the store update test.
Problem: need test coverage for core data operations, inline
metadata parsing, and buffer diff algorithm.
Solution: add busted specs for store CRUD, round-trip
preservation, parse body/command_add with configurable date
syntax, and diff create/delete/update/copy/move operations.