fix(gtasks): async operations, error notifications, buffer refresh

Problem: Sync operations blocked the editor, `push_pass` silently
dropped delete/update/create API errors, and the buffer was not
re-rendered after push/pull/sync.

Solution: Wrap `push`, `pull`, `sync` in `oauth.async()`, add
`vim.notify` for all `push_pass` failure paths, and re-render the
pending buffer after each operation.
This commit is contained in:
Barrett Ruth 2026-03-05 11:18:41 -05:00
parent 84e4a45911
commit 59d2950fda

View file

@ -247,7 +247,9 @@ local function push_pass(access_token, tasklists, s, now_ts, by_gtasks_id)
if task.status == 'deleted' and gtid and list_id then if task.status == 'deleted' and gtid and list_id then
local err = delete_gtask(access_token, list_id, gtid) local err = delete_gtask(access_token, list_id, gtid)
if not err then if err then
vim.notify('pending.nvim: gtasks delete failed: ' .. err, vim.log.levels.WARN)
else
if not task._extra then if not task._extra then
task._extra = {} task._extra = {}
end end
@ -262,7 +264,9 @@ local function push_pass(access_token, tasklists, s, now_ts, by_gtasks_id)
elseif task.status ~= 'deleted' then elseif task.status ~= 'deleted' then
if gtid and list_id then if gtid and list_id then
local err = update_gtask(access_token, list_id, gtid, task_to_gtask(task)) local err = update_gtask(access_token, list_id, gtid, task_to_gtask(task))
if not err then if err then
vim.notify('pending.nvim: gtasks update failed: ' .. err, vim.log.levels.WARN)
else
updated = updated + 1 updated = updated + 1
end end
elseif task.status == 'pending' then elseif task.status == 'pending' then
@ -270,7 +274,9 @@ local function push_pass(access_token, tasklists, s, now_ts, by_gtasks_id)
local lid, err = find_or_create_tasklist(access_token, cat, tasklists) local lid, err = find_or_create_tasklist(access_token, cat, tasklists)
if not err and lid then if not err and lid then
local new_id, create_err = create_gtask(access_token, lid, task_to_gtask(task)) local new_id, create_err = create_gtask(access_token, lid, task_to_gtask(task))
if not create_err and new_id then if create_err then
vim.notify('pending.nvim: gtasks create failed: ' .. create_err, vim.log.levels.WARN)
elseif new_id then
if not task._extra then if not task._extra then
task._extra = {} task._extra = {}
end end
@ -357,61 +363,81 @@ function M.auth()
end end
function M.push() function M.push()
local access_token, tasklists, s, now_ts = sync_setup() oauth.async(function()
if not access_token then local access_token, tasklists, s, now_ts = sync_setup()
return if not access_token then
end return
---@cast tasklists table<string, string> end
---@cast s pending.Store ---@cast tasklists table<string, string>
---@cast now_ts string ---@cast s pending.Store
local by_gtasks_id = build_id_index(s) ---@cast now_ts string
local created, updated, deleted = push_pass(access_token, tasklists, s, now_ts, by_gtasks_id) local by_gtasks_id = build_id_index(s)
s:save() local created, updated, deleted =
require('pending')._recompute_counts() push_pass(access_token, tasklists, s, now_ts, by_gtasks_id)
vim.notify( s:save()
string.format('pending.nvim: Google Tasks pushed — +%d ~%d -%d', created, updated, deleted) require('pending')._recompute_counts()
) local buffer = require('pending.buffer')
if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then
buffer.render(buffer.bufnr())
end
vim.notify(
string.format('pending.nvim: Google Tasks pushed — +%d ~%d -%d', created, updated, deleted)
)
end)
end end
function M.pull() function M.pull()
local access_token, tasklists, s, now_ts = sync_setup() oauth.async(function()
if not access_token then local access_token, tasklists, s, now_ts = sync_setup()
return if not access_token then
end return
---@cast tasklists table<string, string> end
---@cast s pending.Store ---@cast tasklists table<string, string>
---@cast now_ts string ---@cast s pending.Store
local by_gtasks_id = build_id_index(s) ---@cast now_ts string
local created, updated = pull_pass(access_token, tasklists, s, now_ts, by_gtasks_id) local by_gtasks_id = build_id_index(s)
s:save() local created, updated = pull_pass(access_token, tasklists, s, now_ts, by_gtasks_id)
require('pending')._recompute_counts() s:save()
vim.notify(string.format('pending.nvim: Google Tasks pulled — +%d ~%d', created, updated)) require('pending')._recompute_counts()
local buffer = require('pending.buffer')
if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then
buffer.render(buffer.bufnr())
end
vim.notify(string.format('pending.nvim: Google Tasks pulled — +%d ~%d', created, updated))
end)
end end
function M.sync() function M.sync()
local access_token, tasklists, s, now_ts = sync_setup() oauth.async(function()
if not access_token then local access_token, tasklists, s, now_ts = sync_setup()
return if not access_token then
end return
---@cast tasklists table<string, string> end
---@cast s pending.Store ---@cast tasklists table<string, string>
---@cast now_ts string ---@cast s pending.Store
local by_gtasks_id = build_id_index(s) ---@cast now_ts string
local pushed_create, pushed_update, pushed_delete = local by_gtasks_id = build_id_index(s)
push_pass(access_token, tasklists, s, now_ts, by_gtasks_id) local pushed_create, pushed_update, pushed_delete =
local pulled_create, pulled_update = pull_pass(access_token, tasklists, s, now_ts, by_gtasks_id) push_pass(access_token, tasklists, s, now_ts, by_gtasks_id)
s:save() local pulled_create, pulled_update =
require('pending')._recompute_counts() pull_pass(access_token, tasklists, s, now_ts, by_gtasks_id)
vim.notify( s:save()
string.format( require('pending')._recompute_counts()
'pending.nvim: Google Tasks synced — push: +%d ~%d -%d, pull: +%d ~%d', local buffer = require('pending.buffer')
pushed_create, if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then
pushed_update, buffer.render(buffer.bufnr())
pushed_delete, end
pulled_create, vim.notify(
pulled_update string.format(
'pending.nvim: Google Tasks synced — push: +%d ~%d -%d, pull: +%d ~%d',
pushed_create,
pushed_update,
pushed_delete,
pulled_create,
pulled_update
)
) )
) end)
end end
M._due_to_rfc3339 = due_to_rfc3339 M._due_to_rfc3339 = due_to_rfc3339