feat: time-aware due dates, persistent undo, @return audit (#33)

* fix(plugin): allow command chaining with bar separator

Problem: :Pending|only failed because the command definition lacked the
bar attribute, causing | to be consumed as an argument.

Solution: Add bar = true to nvim_create_user_command so | is treated as
a command separator, matching fugitive's :Git behavior.

* refactor(buffer): remove opinionated window options

Problem: The plugin hardcoded number, relativenumber, wrap, spell,
signcolumn, foldcolumn, and cursorline in set_win_options, overriding
user preferences with no way to opt out.

Solution: Remove all cosmetic window options. Users who want them can
set them in after/ftplugin/pending.lua. Only conceallevel,
concealcursor, and winfixheight remain as functionally required.

* feat: time-aware due dates, persistent undo, @return audit

Problem: Due dates had no time component, the undo stack was lost on
restart and stored in a separate file, and many public functions lacked
required @return annotations.

Solution: Add YYYY-MM-DDThh:mm support across parse, views, recur,
complete, and init with time-aware overdue checks. Merge the undo stack
into the task store JSON so a single file holds all state. Add @return
nil annotations to all 27 void public functions across every module.

* feat(parse): flexible time parsing for @ suffix

Problem: the @HH:MM time suffix required zero-padded 24-hour format,
forcing users to write due:tomorrow@14:00 instead of due:tomorrow@2pm.

Solution: add normalize_time() that accepts bare hours (9, 14),
H:MM (9:30), am/pm (2pm, 9:30am, 12am), and existing HH:MM format,
normalizing all to canonical HH:MM on save.

* feat(complete): add info descriptions to omnifunc items

Problem: completion menu items had no description, making it hard to
distinguish between similar entries like date shorthands and recurrence
patterns.

Solution: return { word, info } tables from date_completions() and
recur_completions(), surfacing human-readable descriptions in the
completion popup.

* ci: format
This commit is contained in:
Barrett Ruth 2026-02-25 20:37:50 -05:00 committed by GitHub
parent 72dbf037c7
commit c57cc0845b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 580 additions and 158 deletions

View file

@ -35,7 +35,7 @@ Features: ~
names, month names, ordinals, and more
- Recurring tasks with automatic next-date spawning on completion
- Two views: category (default) and priority flat list
- Multi-level undo (up to 20 `:w` saves, session-only)
- Multi-level undo (up to 20 `:w` saves, persisted across sessions)
- Quick-add from the command line with `:Pending add`
- Quickfix list of overdue/due-today tasks via `:Pending due`
- Foldable category sections (`zc`/`zo`) in category view
@ -149,6 +149,23 @@ token, the `D` prompt, and `:Pending add`.
`soy` / `eoy` January 1 / December 31 of current year
`later` / `someday` Sentinel date (default: `9999-12-30`)
Time suffix: ~ *pending-dates-time*
Any named date or absolute date accepts an `@` time suffix. Supported
formats: `HH:MM` (24h), `H:MM`, bare hour (`9`, `14`), and am/pm
(`2pm`, `9:30am`, `12am`). All forms are normalized to `HH:MM` on save. >
due:tomorrow@2pm " tomorrow at 14:00
due:fri@9 " next Friday at 09:00
due:+1w@17:00 " one week from today at 17:00
due:tomorrow@9:30am " tomorrow at 09:30
due:2026-03-15@08:00 " absolute date with time
due:2026-03-15T14:30 " ISO 8601 datetime (also accepted)
<
Tasks with a time component are not considered overdue until after the
specified time. The time is displayed alongside the date in virtual text
and preserved across recurrence advances.
==============================================================================
RECURRENCE *pending-recurrence*
@ -242,7 +259,7 @@ COMMANDS *pending-commands*
:Pending undo
Undo the last `:w` save, restoring the task store to its previous state.
Equivalent to the `U` buffer-local key (see |pending-mappings|). Up to 20
levels of undo are retained per session.
levels of undo are persisted across sessions.
==============================================================================
MAPPINGS *pending-mappings*
@ -417,6 +434,19 @@ Fields: ~
|pending.GcalConfig|. Omit this field entirely to
disable Google Calendar sync.
==============================================================================
RECIPES *pending-recipes*
Configure blink.cmp to use pending.nvim's omnifunc as a completion source: >lua
require('blink.cmp').setup({
sources = {
per_filetype = {
pending = { 'omni', 'buffer' },
},
},
})
<
==============================================================================
GOOGLE CALENDAR *pending-gcal*