docs(sync): update vimdoc for backend interface

Problem: Vimdoc documents :Pending sync as a bare command that pushes
to Google Calendar, with no mention of backends or the sync table config.

Solution: Update :Pending sync section to show {backend} [{action}]
syntax with examples, add SYNC BACKENDS section documenting the interface
contract, update config example to use sync.gcal, document legacy gcal
migration, and update health check description.
This commit is contained in:
Barrett Ruth 2026-02-26 16:44:30 -05:00
parent 7de9c23ec1
commit 23d34addc8

View file

@ -47,7 +47,7 @@ REQUIREMENTS *pending-requirements*
- Neovim 0.10+
- No external dependencies for local use
- `curl` and `openssl` are required for Google Calendar sync
- `curl` and `openssl` are required for the `gcal` sync backend
==============================================================================
INSTALL *pending-install*
@ -250,10 +250,23 @@ COMMANDS *pending-commands*
Open the list with |:copen| to navigate to each task's category.
*:Pending-sync*
:Pending sync
Push pending tasks that have a due date to Google Calendar as all-day
events. Requires |pending-gcal| to be configured. See |pending-gcal| for
full details on what gets created, updated, and deleted.
:Pending sync {backend} [{action}]
Run a sync action against a named backend. {backend} is required — bare
`:Pending sync` prints a usage message. {action} defaults to `sync`
when omitted. Each backend lives at `lua/pending/sync/<name>.lua`.
Examples: >vim
:Pending sync gcal " runs gcal.sync()
:Pending sync gcal auth " runs gcal.auth()
:Pending sync gcal sync " explicit sync (same as bare)
<
Tab completion after `:Pending sync ` lists discovered backends.
Tab completion after `:Pending sync gcal ` lists available actions.
Built-in backends: ~
`gcal` Google Calendar one-way push. See |pending-gcal|.
*:Pending-undo*
:Pending undo
@ -440,9 +453,11 @@ loads: >lua
next_task = ']t',
prev_task = '[t',
},
gcal = {
calendar = 'Tasks',
credentials_path = '/path/to/client_secret.json',
sync = {
gcal = {
calendar = 'Tasks',
credentials_path = '/path/to/client_secret.json',
},
},
}
<
@ -508,10 +523,16 @@ Fields: ~
vim.g.pending = { debug = true }
<
{sync} (table, default: {}) *pending.SyncConfig*
Sync backend configuration. Each key is a backend
name and the value is the backend-specific config
table. Currently only `gcal` is built-in.
{gcal} (table, default: nil)
Google Calendar sync configuration. See
|pending.GcalConfig|. Omit this field entirely to
disable Google Calendar sync.
Legacy shorthand for `sync.gcal`. If `gcal` is set
but `sync.gcal` is not, the value is migrated
automatically. New configs should use `sync.gcal`
instead. See |pending.GcalConfig|.
==============================================================================
LUA API *pending-api*
@ -632,13 +653,18 @@ not pulled back into pending.nvim.
Configuration: >lua
vim.g.pending = {
gcal = {
calendar = 'Tasks',
credentials_path = '/path/to/client_secret.json',
sync = {
gcal = {
calendar = 'Tasks',
credentials_path = '/path/to/client_secret.json',
},
},
}
<
The legacy `gcal` top-level key is still accepted and migrated automatically.
New configurations should use `sync.gcal`.
*pending.GcalConfig*
Fields: ~
{calendar} (string, default: 'Pendings')
@ -654,7 +680,7 @@ Fields: ~
that Google provides or as a bare credentials object.
OAuth flow: ~
On the first `:Pending sync` call the plugin detects that no refresh token
On the first `:Pending sync gcal` call the plugin detects that no refresh token
exists and opens the Google authorization URL in the browser using
|vim.ui.open()|. A temporary local HTTP server listens on port 18392 for the
OAuth redirect. The PKCE (Proof Key for Code Exchange) flow is used —
@ -664,7 +690,7 @@ authorization code is exchanged for tokens and the refresh token is stored at
use the stored refresh token and refresh the access token automatically when
it is about to expire.
`:Pending sync` behavior: ~
`:Pending sync gcal` behavior: ~
For each task in the store:
- A pending task with a due date and no existing event: a new all-day event is
created and the event ID is stored in the task's `_extra` table.
@ -677,6 +703,30 @@ For each task in the store:
A summary notification is shown after sync: `created: N, updated: N,
deleted: N`.
==============================================================================
SYNC BACKENDS *pending-sync-backend*
Sync backends are Lua modules under `lua/pending/sync/<name>.lua`. Each
module returns a table conforming to the backend interface: >lua
---@class pending.SyncBackend
---@field name string
---@field auth fun(): nil
---@field sync fun(): nil
---@field health? fun(): nil
<
Required fields: ~
{name} Backend identifier (matches the filename).
{sync} Main sync action. Called by `:Pending sync <name>`.
{auth} Authorization flow. Called by `:Pending sync <name> auth`.
Optional fields: ~
{health} Called by `:checkhealth pending` to report backend-specific
diagnostics (e.g. checking for external tools).
Backend-specific configuration goes under `sync.<name>` in |pending-config|.
==============================================================================
HIGHLIGHT GROUPS *pending-highlights*
@ -728,8 +778,8 @@ Checks performed: ~
- Whether the data directory exists (warning if not yet created)
- Whether the data file exists and can be parsed; reports total task count
- Validates recurrence specs on stored tasks
- Whether `curl` is available (required for Google Calendar sync)
- Whether `openssl` is available (required for OAuth PKCE)
- Discovers sync backends under `lua/pending/sync/` and runs each backend's
`health()` function if it exists (e.g. gcal checks for `curl` and `openssl`)
==============================================================================
DATA FORMAT *pending-data*