pending.nvim/lua/pending/config.lua
Barrett Ruth a24521ee4e
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).
2026-02-26 23:25:39 -05:00

113 lines
2.5 KiB
Lua

---@class pending.Icons
---@field pending string
---@field done string
---@field priority string
---@field header string
---@field due string
---@field recur string
---@field category string
---@class pending.GcalConfig
---@field calendar? string
---@field credentials_path? string
---@class pending.SyncConfig
---@field gcal? pending.GcalConfig
---@class pending.Keymaps
---@field close? string|false
---@field toggle? string|false
---@field view? string|false
---@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
---@field i_task? string|false
---@field a_category? string|false
---@field i_category? string|false
---@field next_header? string|false
---@field prev_header? string|false
---@field next_task? string|false
---@field prev_task? string|false
---@class pending.Config
---@field data_path string
---@field default_view 'category'|'priority'
---@field default_category string
---@field date_format string
---@field date_syntax string
---@field recur_syntax string
---@field someday_date string
---@field category_order? string[]
---@field drawer_height? integer
---@field debug? boolean
---@field keymaps pending.Keymaps
---@field sync? pending.SyncConfig
---@field icons pending.Icons
---@class pending.config
local M = {}
---@type pending.Config
local defaults = {
data_path = vim.fn.stdpath('data') .. '/pending/tasks.json',
default_view = 'category',
default_category = 'Todo',
date_format = '%b %d',
date_syntax = 'due',
recur_syntax = 'rec',
someday_date = '9999-12-30',
category_order = {},
keymaps = {
close = 'q',
toggle = '<CR>',
view = '<Tab>',
priority = '!',
date = 'D',
undo = 'U',
filter = 'F',
open_line = 'o',
open_line_above = 'O',
a_task = 'at',
i_task = 'it',
a_category = 'aC',
i_category = 'iC',
next_header = ']]',
prev_header = '[[',
next_task = ']t',
prev_task = '[t',
},
sync = {},
icons = {
pending = '',
done = '',
priority = '',
header = '',
due = '·',
recur = '',
category = '#',
},
}
---@type pending.Config?
local _resolved = nil
---@return pending.Config
function M.get()
if _resolved then
return _resolved
end
local user = vim.g.pending or {}
_resolved = vim.tbl_deep_extend('force', defaults, user)
return _resolved
end
---@return nil
function M.reset()
_resolved = nil
end
return M