docs: document S3 backend, auto-auth, and :Pending done command (#125)

Problem: The S3 backend had no `:Pending s3` entry in the COMMANDS
section, `:Pending auth` only mentioned Google, the `sync` config
field omitted `s3`, `_s3_sync_id` was missing from the data format
section, `:Pending done` was implemented but undocumented, and the
README lacked a features overview.

Solution: Add `:Pending s3` and `:Pending done` command docs, rewrite
`:Pending auth` to cover all backends and sub-actions, update config
and data format references, add `aws` CLI to requirements, and add a
Features section to `README.md`.
This commit is contained in:
Barrett Ruth 2026-03-10 14:31:48 -04:00 committed by GitHub
parent fec03b3dcd
commit 0d4d3fead6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 86 additions and 15 deletions

View file

@ -8,10 +8,27 @@ Oil-like task management for todos in Neovim, inspired by
https://github.com/user-attachments/assets/f3898ecb-ec95-43fe-a71f-9c9f49628ba9 https://github.com/user-attachments/assets/f3898ecb-ec95-43fe-a71f-9c9f49628ba9
## Features
- Oil-style buffer editing: standard Vim motions for all task operations
- Inline metadata: `due:`, `cat:`, `rec:` tokens parsed on `:w`
- Rich date input: relative (`+3d`, `tomorrow`), weekdays, ordinals, custom formats, time suffixes
- Recurring tasks with automatic next-date spawning on completion
- Category and queue views with foldable sections
- Multi-level undo (up to 20 saves, persisted across sessions)
- Text objects (`at`/`it`/`aC`/`iC`) and motions (`]]`/`[[`/`]t`/`[t`)
- Omnifunc completion for `due:`, `cat:`, and `rec:` tokens
- Filters: `cat:X`, `overdue`, `today`, `priority`, `wip`, `blocked`
- Google Calendar one-way push via OAuth PKCE
- Google Tasks bidirectional sync via OAuth PKCE
- S3 whole-store sync via AWS CLI with cross-device merge
- Auto-authentication: sync actions trigger auth flows automatically
## Requirements ## Requirements
- Neovim 0.10+ - Neovim 0.10+
- (Optionally) `curl` for Google Calendar and Google Task sync - (Optionally) `curl` for Google Calendar and Google Tasks sync
- (Optionally) `aws` CLI for S3 sync
## Installation ## Installation

View file

@ -42,6 +42,7 @@ Features: ~
- 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 - Google Tasks bidirectional sync via OAuth PKCE
- S3 whole-store sync via AWS CLI
============================================================================== ==============================================================================
CONTENTS *pending-contents* CONTENTS *pending-contents*
@ -76,6 +77,7 @@ REQUIREMENTS *pending-requirements*
- Neovim 0.10+ - Neovim 0.10+
- No external dependencies for local use - No external dependencies for local use
- `curl` is required for the `gcal` and `gtasks` sync backends - `curl` is required for the `gcal` and `gtasks` sync backends
- `aws` CLI is required for the `s3` sync backend
============================================================================== ==============================================================================
INSTALL *pending-install* INSTALL *pending-install*
@ -167,13 +169,34 @@ COMMANDS *pending-commands*
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-auth* *:Pending-auth*
:Pending auth :Pending auth [{backend} [{sub-action}]]
Authorize pending.nvim to access Google services (Tasks and Calendar). Authenticate a sync backend. Without arguments, prompts with
Prompts with |vim.ui.select| to choose gtasks, gcal, or both — all |vim.ui.select| when multiple backends have auth methods. With an
options run the same combined OAuth flow and produce a single shared explicit {backend} name, dispatches directly: >vim
token file. If no credentials are configured, the setup wizard runs :Pending auth gcal
first to collect a client ID and secret. :Pending auth gtasks
See |pending-google-auth| for full details. :Pending auth s3
:Pending auth gcal clear
:Pending auth gtasks reset
:Pending auth s3 profile
<
Google backends (gcal, gtasks): ~
Both share a single OAuth flow with combined scopes. If no credentials
are configured (bundled placeholders in use), the setup wizard runs
first to collect a client ID and secret. Sub-actions:
`clear` Remove OAuth tokens (forces re-authentication).
`reset` Remove tokens and credentials (full reset).
See |pending-google-auth| for details.
S3 backend: ~
Runs `aws sts get-caller-identity` to verify AWS credentials. If the
profile uses SSO and the session has expired, runs `aws sso login`
automatically. Sub-actions:
`profile` Prompt for an AWS profile name.
See |pending-s3| for details.
Auth is triggered automatically when running sync actions without valid
credentials. See |pending-sync-auto-auth|.
*:Pending-gtasks* *:Pending-gtasks*
:Pending gtasks {action} :Pending gtasks {action}
@ -207,6 +230,34 @@ COMMANDS *pending-commands*
Tab completion after `:Pending gcal ` lists available actions. Tab completion after `:Pending gcal ` lists available actions.
See |pending-gcal| for full details. See |pending-gcal| for full details.
*:Pending-s3*
:Pending s3 {action}
Run an S3 sync action. An explicit action is required.
Actions: ~
`sync` Pull remote changes then push merged result.
`push` Upload the local store to S3.
`pull` Download the remote store and merge into local.
Examples: >vim
:Pending s3 sync " pull then push
:Pending s3 push " upload local → S3
:Pending s3 pull " download S3 → local
<
Tab completion after `:Pending s3 ` lists available actions.
See |pending-s3| for full details.
*:Pending-done*
:Pending done [{id}]
Mark a task as done without opening the buffer. {id} is the numeric task
ID. When {id} is omitted and the task buffer is open, the task under the
cursor is used. Recurring tasks spawn a new pending instance with the
next due date. >vim
:Pending done 5
:Pending done
<
*:Pending-filter* *:Pending-filter*
:Pending filter {predicates} :Pending filter {predicates}
Apply a filter to the task buffer. {predicates} is a space-separated list Apply a filter to the task buffer. {predicates} is a space-separated list
@ -862,9 +913,11 @@ Fields: ~
{sync} (table, default: {}) *pending.SyncConfig* {sync} (table, default: {}) *pending.SyncConfig*
Sync backend configuration. Each key is a backend Sync backend configuration. Each key is a backend
name and the value is the backend-specific config name and the value is the backend-specific config
table. Built-in backends: `gcal`, `gtasks`. Both table. Built-in backends: `gcal`, `gtasks`, `s3`.
ship bundled OAuth credentials so no setup is Google backends ship bundled OAuth credentials so
needed beyond `:Pending <backend> auth`. no setup is needed beyond `:Pending auth`. The S3
backend delegates to the AWS CLI credential chain.
See |pending-gcal|, |pending-gtasks|, |pending-s3|.
{icons} (table) *pending.Icons* {icons} (table) *pending.Icons*
Icon characters displayed in the buffer. The Icon characters displayed in the buffer. The
@ -1424,10 +1477,11 @@ Task fields: ~
{order} (integer) Relative ordering within a category. {order} (integer) Relative ordering within a category.
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 sync backend metadata:
(`_gcal_event_id`) and Google Tasks IDs (`_gtasks_task_id`, - Google Calendar: `_gcal_event_id`, `_gcal_calendar_id`
`_gtasks_list_id`), and allows third-party tooling to annotate tasks without - Google Tasks: `_gtasks_task_id`, `_gtasks_list_id`
data loss. - S3: `_s3_sync_id` (UUID for cross-device merge)
Third-party tooling can annotate tasks via `_extra` without 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
version the plugin supports, loading is aborted with an error message asking version the plugin supports, loading is aborted with an error message asking