feat(filter): wire F key and <Plug>(pending-filter) mapping (#53)

* refactor(config): remove legacy gcal top-level config key

Problem: the gcal migration shim silently accepted vim.g.pending = { gcal
= {...} } and copied it to sync.gcal, adding complexity and a deprecated
API surface.

Solution: remove the migration block in config.get(), drop the cfg.gcal
fallback in gcal_config(), delete the two migration tests, and clean up
the vimdoc references. Callers must now use sync.gcal directly.

* ci: fix

* fix(spec): remove duplicate buffer require in complete_spec

* docs(pending): reorganize vimdoc and fix incorrect defaults

Problem: sections were out of logical order — inline metadata appeared
before commands, GCal before its own backend framework, store resolution
duplicated and buried after health check. Two defaults were wrong:
default_category documented as 'Inbox' (should be 'Todo') and the gcal
calendar example used 'Tasks' (should be 'Pendings').

Solution: reorder all 21 sections into onboarding-first flow, add a
CONTENTS table with hyperlinks, fix both incorrect defaults in every
location they appeared, and remove the duplicate STORE RESOLUTION
section.

* feat(filter): wire F key and <Plug>(pending-filter) mapping

Problem: the filter predicate logic, diff guard, _on_write handling,
:Pending filter command, and filter_spec were already implemented, but
there was no buffer-local key to invoke filtering interactively.

Solution: add filter = 'F' to keymaps config and defaults, wire the
filter action in _setup_buf_mappings via vim.ui.input, add
<Plug>(pending-filter), and update the vimdoc (mappings table, Plug
section, config example, and FILTERS section).
This commit is contained in:
Barrett Ruth 2026-02-26 23:25:39 -05:00
parent 2b87337d78
commit 5adf2341f3
4 changed files with 25 additions and 1 deletions

View file

@ -244,6 +244,7 @@ Default buffer-local keys: ~
`<CR>` Toggle complete / uncomplete (`toggle`)
`!` Toggle the priority flag (`priority`)
`D` Prompt for a due date (`date`)
`F` Prompt for filter predicates (`filter`)
`<Tab>` Switch between category / queue view (`view`)
`U` Undo the last `:w` save (`undo`)
`o` Insert a new task line below (`open_line`)
@ -309,6 +310,10 @@ All motions support count: `3]]` jumps three headers forward. `]]` and
<Plug>(pending-undo)
Undo the last `:w` save.
*<Plug>(pending-filter)*
<Plug>(pending-filter)
Prompt for filter predicates via |vim.ui.input|.
*<Plug>(pending-open-line)*
<Plug>(pending-open-line)
Insert a correctly-formatted blank task line below the cursor.
@ -385,7 +390,8 @@ Hidden tasks are preserved in the store and reappear when the filter is
cleared. Filter state is session-local — it does not persist across Neovim
restarts.
Set a filter with |:Pending-filter| or by editing the `FILTER:` line: >vim
Set a filter with |:Pending-filter|, the `F` buffer key, or by editing the
`FILTER:` line: >vim
:Pending filter cat:Work overdue
<
@ -567,6 +573,7 @@ loads: >lua
priority = '!',
date = 'D',
undo = 'U',
filter = 'F',
open_line = 'o',
open_line_above = 'O',
a_task = 'at',

View file

@ -21,6 +21,7 @@
---@field priority? string|false
---@field date? string|false
---@field undo? string|false
---@field filter? string|false
---@field open_line? string|false
---@field open_line_above? string|false
---@field a_task? string|false
@ -67,6 +68,7 @@ local defaults = {
priority = '!',
date = 'D',
undo = 'U',
filter = 'F',
open_line = 'o',
open_line_above = 'O',
a_task = 'at',

View file

@ -243,6 +243,13 @@ function M._setup_buf_mappings(bufnr)
undo = function()
M.undo_write()
end,
filter = function()
vim.ui.input({ prompt = 'Filter: ' }, function(input)
if input then
M.filter(input)
end
end)
end,
open_line = function()
buffer.open_line(false)
end,

View file

@ -258,6 +258,14 @@ vim.keymap.set('n', '<Plug>(pending-undo)', function()
require('pending').undo_write()
end)
vim.keymap.set('n', '<Plug>(pending-filter)', function()
vim.ui.input({ prompt = 'Filter: ' }, function(input)
if input then
require('pending').filter(input)
end
end)
end)
vim.keymap.set('n', '<Plug>(pending-open-line)', function()
require('pending.buffer').open_line(false)
end)