* feat(config): add icons table with unicode defaults * feat(buffer): render icon overlays from config.icons Problem: status characters ([ ], [x], [!]) and metadata prefixes are hardcoded literals with no user customization. Solution: read config.icons in apply_extmarks and apply overlay extmarks for checkboxes/headers, replace hardcoded recur ↺ with icons.recur, and prefix due/category virt_text with configurable icon characters. * feat(plugin): add PendingTab command and <Plug>(pending-tab) * docs: add icons config, PendingTab recipes, and demo infrastructure Problem: icon customization and auto-start workflow are undocumented; no demo asset exists for the README. Solution: document pending.Icons in vimdoc with nerd font and ASCII recipes, add PendingTab to commands and mappings, add open-on-startup recipe, add demo-init.lua and demo.tape for VHS screenshot generation, add assets/ directory, add README icons section and demo placeholder. * ci: format
117 lines
2.7 KiB
Lua
117 lines
2.7 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 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
|
|
---@field goto_file? 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 gcal? pending.GcalConfig
|
|
---@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',
|
|
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)
|
|
if _resolved.gcal and not (_resolved.sync and _resolved.sync.gcal) then
|
|
_resolved.sync = _resolved.sync or {}
|
|
_resolved.sync.gcal = _resolved.gcal
|
|
end
|
|
return _resolved
|
|
end
|
|
|
|
---@return nil
|
|
function M.reset()
|
|
_resolved = nil
|
|
end
|
|
|
|
return M
|