docs(gtasks): document Google Tasks backend and CLI changes
Problem: vimdoc had no coverage for the gtasks backend and still referenced the old `:Pending sync <backend>` command form. Solution: add `:Pending-gtasks` and `:Pending-gcal` command sections with per-action docs, update sync backend interface, and add gtasks config example.
This commit is contained in:
parent
ffc588ccf9
commit
e8894d7d8b
1 changed files with 115 additions and 21 deletions
136
doc/pending.txt
136
doc/pending.txt
|
|
@ -41,6 +41,7 @@ Features: ~
|
||||||
- Foldable category sections (`zc`/`zo`) in category view
|
- Foldable category sections (`zc`/`zo`) in category view
|
||||||
- Omnifunc completion for `cat:`, `due:`, and `rec:` tokens (`<C-x><C-o>`)
|
- Omnifunc completion for `cat:`, `due:`, and `rec:` tokens (`<C-x><C-o>`)
|
||||||
- Google Calendar one-way push via OAuth PKCE
|
- Google Calendar one-way push via OAuth PKCE
|
||||||
|
- Google Tasks bidirectional sync via OAuth PKCE
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
CONTENTS *pending-contents*
|
CONTENTS *pending-contents*
|
||||||
|
|
@ -63,15 +64,16 @@ CONTENTS *pending-contents*
|
||||||
16. Recipes ............................................... |pending-recipes|
|
16. Recipes ............................................... |pending-recipes|
|
||||||
17. Sync Backends ................................... |pending-sync-backend|
|
17. Sync Backends ................................... |pending-sync-backend|
|
||||||
18. Google Calendar .......................................... |pending-gcal|
|
18. Google Calendar .......................................... |pending-gcal|
|
||||||
19. Data Format .............................................. |pending-data|
|
19. Google Tasks ............................................ |pending-gtasks|
|
||||||
20. Health Check ........................................... |pending-health|
|
20. Data Format .............................................. |pending-data|
|
||||||
|
21. Health Check ........................................... |pending-health|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
REQUIREMENTS *pending-requirements*
|
REQUIREMENTS *pending-requirements*
|
||||||
|
|
||||||
- Neovim 0.10+
|
- Neovim 0.10+
|
||||||
- No external dependencies for local use
|
- No external dependencies for local use
|
||||||
- `curl` and `openssl` are required for the `gcal` sync backend
|
- `curl` and `openssl` are required for the `gcal` and `gtasks` sync backends
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
INSTALL *pending-install*
|
INSTALL *pending-install*
|
||||||
|
|
@ -146,24 +148,42 @@ COMMANDS *pending-commands*
|
||||||
Populate the quickfix list with all tasks that are overdue or due today.
|
Populate the quickfix list with all tasks that are overdue or due today.
|
||||||
Open the list with |:copen| to navigate to each task's category.
|
Open the list with |:copen| to navigate to each task's category.
|
||||||
|
|
||||||
*:Pending-sync*
|
*:Pending-gtasks*
|
||||||
:Pending sync {backend} [{action}]
|
:Pending gtasks [{action}]
|
||||||
Run a sync action against a named backend. {backend} is required — bare
|
Run a Google Tasks sync action. {action} defaults to `sync` when omitted.
|
||||||
`:Pending sync` prints a usage message. {action} defaults to `sync`
|
|
||||||
when omitted. Each backend lives at `lua/pending/sync/<name>.lua`.
|
Actions: ~
|
||||||
|
`sync` Push local changes then pull remote changes (default).
|
||||||
|
`push` Push local changes to Google Tasks only.
|
||||||
|
`pull` Pull remote changes from Google Tasks only.
|
||||||
|
`auth` Run the OAuth authorization flow.
|
||||||
|
|
||||||
Examples: >vim
|
Examples: >vim
|
||||||
:Pending sync gcal " runs gcal.sync()
|
:Pending gtasks " push then pull (default)
|
||||||
:Pending sync gcal auth " runs gcal.auth()
|
:Pending gtasks push " push local → Google Tasks
|
||||||
:Pending sync gcal sync " explicit sync (same as bare)
|
:Pending gtasks pull " pull Google Tasks → local
|
||||||
|
:Pending gtasks auth " authorize
|
||||||
<
|
<
|
||||||
|
|
||||||
Tab completion after `:Pending sync ` lists discovered backends.
|
Tab completion after `:Pending gtasks ` lists available actions.
|
||||||
Tab completion after `:Pending sync gcal ` lists available actions.
|
See |pending-gtasks| for full details.
|
||||||
|
|
||||||
Built-in backends: ~
|
*:Pending-gcal*
|
||||||
|
:Pending gcal [{action}]
|
||||||
|
Run a Google Calendar sync action. {action} defaults to `sync` when
|
||||||
|
omitted.
|
||||||
|
|
||||||
`gcal` Google Calendar one-way push. See |pending-gcal|.
|
Actions: ~
|
||||||
|
`sync` Push tasks with due dates to Google Calendar (default).
|
||||||
|
`auth` Run the OAuth authorization flow.
|
||||||
|
|
||||||
|
Examples: >vim
|
||||||
|
:Pending gcal " push to Google Calendar (default)
|
||||||
|
:Pending gcal auth " authorize
|
||||||
|
<
|
||||||
|
|
||||||
|
Tab completion after `:Pending gcal ` lists available actions.
|
||||||
|
See |pending-gcal| for full details.
|
||||||
|
|
||||||
*:Pending-filter*
|
*:Pending-filter*
|
||||||
:Pending filter {predicates}
|
:Pending filter {predicates}
|
||||||
|
|
@ -590,6 +610,9 @@ loads: >lua
|
||||||
calendar = 'Pendings',
|
calendar = 'Pendings',
|
||||||
credentials_path = '/path/to/client_secret.json',
|
credentials_path = '/path/to/client_secret.json',
|
||||||
},
|
},
|
||||||
|
gtasks = {
|
||||||
|
credentials_path = '/path/to/client_secret.json',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
<
|
<
|
||||||
|
|
@ -870,21 +893,30 @@ Open tasks in a new tab on startup: >lua
|
||||||
SYNC BACKENDS *pending-sync-backend*
|
SYNC BACKENDS *pending-sync-backend*
|
||||||
|
|
||||||
Sync backends are Lua modules under `lua/pending/sync/<name>.lua`. Each
|
Sync backends are Lua modules under `lua/pending/sync/<name>.lua`. Each
|
||||||
module returns a table conforming to the backend interface: >lua
|
backend is exposed as a top-level `:Pending` subcommand: >vim
|
||||||
|
:Pending gtasks [action]
|
||||||
|
:Pending gcal [action]
|
||||||
|
<
|
||||||
|
|
||||||
|
Each module returns a table conforming to the backend interface: >lua
|
||||||
|
|
||||||
---@class pending.SyncBackend
|
---@class pending.SyncBackend
|
||||||
---@field name string
|
---@field name string
|
||||||
---@field auth fun(): nil
|
---@field auth fun(): nil
|
||||||
---@field sync fun(): nil
|
---@field sync fun(): nil
|
||||||
|
---@field push? fun(): nil
|
||||||
|
---@field pull? fun(): nil
|
||||||
---@field health? fun(): nil
|
---@field health? fun(): nil
|
||||||
<
|
<
|
||||||
|
|
||||||
Required fields: ~
|
Required fields: ~
|
||||||
{name} Backend identifier (matches the filename).
|
{name} Backend identifier (matches the filename).
|
||||||
{sync} Main sync action. Called by `:Pending sync <name>`.
|
{sync} Main sync action. Called by `:Pending <name>`.
|
||||||
{auth} Authorization flow. Called by `:Pending sync <name> auth`.
|
{auth} Authorization flow. Called by `:Pending <name> auth`.
|
||||||
|
|
||||||
Optional fields: ~
|
Optional fields: ~
|
||||||
|
{push} Push-only action. Called by `:Pending <name> push`.
|
||||||
|
{pull} Pull-only action. Called by `:Pending <name> pull`.
|
||||||
{health} Called by `:checkhealth pending` to report backend-specific
|
{health} Called by `:checkhealth pending` to report backend-specific
|
||||||
diagnostics (e.g. checking for external tools).
|
diagnostics (e.g. checking for external tools).
|
||||||
|
|
||||||
|
|
@ -923,7 +955,7 @@ Fields: ~
|
||||||
that Google provides or as a bare credentials object.
|
that Google provides or as a bare credentials object.
|
||||||
|
|
||||||
OAuth flow: ~
|
OAuth flow: ~
|
||||||
On the first `:Pending sync gcal` call the plugin detects that no refresh token
|
On the first `:Pending gcal` call the plugin detects that no refresh token
|
||||||
exists and opens the Google authorization URL in the browser using
|
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
|
|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 —
|
OAuth redirect. The PKCE (Proof Key for Code Exchange) flow is used —
|
||||||
|
|
@ -933,7 +965,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
|
use the stored refresh token and refresh the access token automatically when
|
||||||
it is about to expire.
|
it is about to expire.
|
||||||
|
|
||||||
`:Pending sync gcal` behavior: ~
|
`:Pending gcal` behavior: ~
|
||||||
For each task in the store:
|
For each task in the store:
|
||||||
- A pending task with a due date and no existing event: a new all-day event is
|
- 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.
|
created and the event ID is stored in the task's `_extra` table.
|
||||||
|
|
@ -946,6 +978,67 @@ For each task in the store:
|
||||||
A summary notification is shown after sync: `created: N, updated: N,
|
A summary notification is shown after sync: `created: N, updated: N,
|
||||||
deleted: N`.
|
deleted: N`.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
GOOGLE TASKS *pending-gtasks*
|
||||||
|
|
||||||
|
pending.nvim can sync tasks bidirectionally with Google Tasks. Each
|
||||||
|
pending.nvim category maps to a Google Tasks list of the same name. Lists are
|
||||||
|
created automatically on first sync.
|
||||||
|
|
||||||
|
Configuration: >lua
|
||||||
|
vim.g.pending = {
|
||||||
|
sync = {
|
||||||
|
gtasks = {
|
||||||
|
credentials_path = '/path/to/client_secret.json',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
<
|
||||||
|
|
||||||
|
*pending.GtasksConfig*
|
||||||
|
Fields: ~
|
||||||
|
{credentials_path} (string)
|
||||||
|
Path to the OAuth client secret JSON file downloaded
|
||||||
|
from the Google Cloud Console. Default:
|
||||||
|
`stdpath('data')..'/pending/gtasks_credentials.json'`.
|
||||||
|
Accepts the `installed` wrapper format or a bare
|
||||||
|
credentials object.
|
||||||
|
|
||||||
|
OAuth flow: ~
|
||||||
|
Same PKCE flow as the gcal backend; listens on port 18393. Tokens are stored
|
||||||
|
at `stdpath('data')/pending/gtasks_tokens.json`. Run `:Pending gtasks auth`
|
||||||
|
to authorize; subsequent syncs refresh the token automatically.
|
||||||
|
|
||||||
|
`:Pending gtasks` actions: ~
|
||||||
|
|
||||||
|
`:Pending gtasks` (or `:Pending gtasks sync`) runs push then pull. Use
|
||||||
|
`:Pending gtasks push` or `:Pending gtasks pull` to run only one direction.
|
||||||
|
|
||||||
|
Push (local → Google Tasks, `:Pending gtasks push`):
|
||||||
|
- Pending task with no `_gtasks_task_id`: created in the matching list.
|
||||||
|
- Pending task with an existing ID: updated in Google Tasks.
|
||||||
|
- Done task with an existing ID: marked `completed` in Google Tasks.
|
||||||
|
- Deleted task with an existing ID: deleted from Google Tasks.
|
||||||
|
|
||||||
|
Pull (Google Tasks → local, `:Pending gtasks pull`):
|
||||||
|
- GTasks task already known (matched by `_gtasks_task_id`): updated locally
|
||||||
|
if `gtasks.updated` timestamp is newer than `task.modified`.
|
||||||
|
- GTasks task not known locally: created as a new pending.nvim task in the
|
||||||
|
category matching the list name.
|
||||||
|
|
||||||
|
Field mapping: ~
|
||||||
|
{title} ↔ task description
|
||||||
|
{status} `needsAction` ↔ `pending`, `completed` ↔ `done`
|
||||||
|
{due} date-only; time component ignored (GTasks limitation)
|
||||||
|
{notes} serializes extra fields: `pri:1 rec:weekly`
|
||||||
|
|
||||||
|
The `notes` field is used exclusively for pending.nvim metadata. Any existing
|
||||||
|
notes on tasks created outside pending.nvim are parsed for known tokens and
|
||||||
|
the remainder is ignored.
|
||||||
|
|
||||||
|
Recurrence (`rec:`) is stored in notes for round-tripping but is not
|
||||||
|
expanded by Google Tasks (GTasks has no recurrence API).
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
DATA FORMAT *pending-data*
|
DATA FORMAT *pending-data*
|
||||||
|
|
||||||
|
|
@ -979,7 +1072,8 @@ Task fields: ~
|
||||||
|
|
||||||
Any field not in the list above is preserved in `_extra` and written back on
|
Any field not in the list above is preserved in `_extra` and written back on
|
||||||
save. This is used internally to store the Google Calendar event ID
|
save. This is used internally to store the Google Calendar event ID
|
||||||
(`_gcal_event_id`) and allows third-party tooling to annotate tasks without
|
(`_gcal_event_id`) and Google Tasks IDs (`_gtasks_task_id`,
|
||||||
|
`_gtasks_list_id`), and allows third-party tooling to annotate tasks without
|
||||||
data loss.
|
data loss.
|
||||||
|
|
||||||
The `version` field is checked on load. If the file version is newer than the
|
The `version` field is checked on load. If the file version is newer than the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue