feat(buffer): add configurable eol_format for EOL virtual text

Problem: EOL virtual text order (category → recurrence → due) and the
double-space separator are hardcoded in `apply_extmarks()`. Users cannot
reorder, omit, or restyle metadata fields.

Solution: Add `eol_format` config field (default `'%c  %r  %d'`) with
`%c`, `%r`, `%d` specifiers. `parse_eol_format()` tokenizes the format
string; `build_eol_virt()` resolves specifiers against `LineMeta` and
collapses literals around absent fields.
This commit is contained in:
Barrett Ruth 2026-03-08 14:25:22 -04:00
parent 27f46ae0dd
commit b6c28eb7b3
3 changed files with 116 additions and 15 deletions

View file

@ -648,6 +648,32 @@ Fields: ~
virtual text in the buffer. Examples: `'%Y-%m-%d'`
for ISO dates, `'%d %b'` for day-first.
{eol_format} (string, default: '%c %r %d')
Format string controlling the order, content, and
separators of end-of-line virtual text on task lines.
Three specifiers are available:
`%c` category icon + name (`PendingHeader`)
`%r` recurrence icon + pattern (`PendingRecur`)
`%d` due icon + date (`PendingDue` / `PendingOverdue`)
Literal text between specifiers is rendered with the
`Normal` highlight group and acts as a separator.
When a specifier's data is absent (e.g. `%d` on a
task with no due date), the specifier and any
surrounding literal text up to the next specifier
are omitted — missing fields never leave gaps.
`%c` only renders in priority view (where
`show_category` is true). In category view it is
always omitted regardless of the format string.
Examples: >lua
vim.g.pending = { eol_format = '%d %r' }
vim.g.pending = { eol_format = '%d | %r' }
vim.g.pending = { eol_format = '%c %d %r' }
<
{input_date_formats} (string[], default: {}) *pending-input-formats*
List of strftime-like format strings tried in order
when parsing a `due:` token that does not match the