feat: add markdown detail buffer for task notes

Problem: tasks only have a one-line description. There is no way to
attach extended notes, checklists, or context to a task.

Solution: add `ge` keymap to open a `pending://task/<id>` markdown
buffer that replaces the task list in the same split. The buffer shows
a read-only metadata header (status, priority, category, due,
recurrence) rendered via extmarks, a `---` separator, and editable
notes below. `:w` saves notes to a new top-level `notes` field on the
task stored in the single `tasks.json`. `q` returns to the task list.
This commit is contained in:
Barrett Ruth 2026-03-13 08:18:49 -04:00
parent 0b0b64fc3d
commit d7d79b5b87
Signed by: barrett
GPG key ID: A6C96C9349D2FC81
7 changed files with 298 additions and 0 deletions

View file

@ -348,6 +348,7 @@ Default buffer-local keys: ~
`gw` Toggle work-in-progress status (`wip`)
`gb` Toggle blocked status (`blocked`)
`g/` Toggle cancelled status (`cancelled`)
`ge` Open markdown detail buffer for task notes (`edit_notes`)
`gf` Prompt for filter predicates (`filter`)
`<Tab>` Switch between category / queue view (`view`)
`gz` Undo the last `:w` save (`undo`)
@ -487,6 +488,12 @@ old keys to `false`: >lua
Decrement the priority level for the task under the cursor, clamped
at 0. Default key: `<C-x>`.
*<Plug>(pending-edit-notes)*
<Plug>(pending-edit-notes)
Open the markdown detail buffer for the task under the cursor.
Shows a read-only metadata header and editable notes below a `---`
separator. Press `q` to return to the task list. Default key: `ge`.
*<Plug>(pending-open-line)*
<Plug>(pending-open-line)
Insert a correctly-formatted blank task line below the cursor.
@ -557,6 +564,29 @@ Queue view: ~ *pending-view-queue*
virtual text so tasks remain identifiable across categories. The
buffer is named `pending://queue`.
==============================================================================
DETAIL BUFFER *pending-detail-buffer*
Press `ge` (or `keymaps.edit_notes`) on a task to open a markdown detail
buffer named `pending://task/<id>`. The buffer replaces the task list in
the same split.
Layout: ~
Line 1: `# <description>` (task description as heading)
Lines 2-3: Read-only metadata (status, priority, category, due,
recurrence) rendered as virtual text overlays
Line 4: `---` separator
Line 5+: Free-form markdown notes (editable)
The metadata header is not editable — it is rendered via extmarks on
empty buffer lines. To change metadata, return to the task list and use
the normal keymaps or `:Pending edit`.
Write (`:w`) saves the notes content (everything below the `---`
separator) to the `notes` field in the task store. Press `q` to return
to the task list.
==============================================================================
FILTERS *pending-filters*
@ -789,6 +819,7 @@ loads: >lua
wip = 'gw',
blocked = 'gb',
cancelled = 'g/',
edit_notes = 'ge',
},
sync = {
gcal = {},
@ -1651,6 +1682,7 @@ Task fields: ~
{entry} (string) ISO 8601 UTC timestamp of creation.
{modified} (string) ISO 8601 UTC timestamp of last modification.
{end} (string) ISO 8601 UTC timestamp of completion or deletion.
{notes} (string) Free-form markdown notes (from detail buffer).
{order} (integer) Relative ordering within a category.
Any field not in the list above is preserved in `_extra` and written back on