diff --git a/lua/pending/buffer.lua b/lua/pending/buffer.lua index adcf2dc..827ff82 100644 --- a/lua/pending/buffer.lua +++ b/lua/pending/buffer.lua @@ -133,7 +133,6 @@ function M.open_line(above) local insert_row = above and (row - 1) or row vim.bo[bufnr].modifiable = true vim.api.nvim_buf_set_lines(bufnr, insert_row, insert_row, false, { '- [ ] ' }) - table.insert(_meta, insert_row + 1, { type = 'task' }) vim.api.nvim_win_set_cursor(0, { insert_row + 1, 6 }) vim.cmd('startinsert!') end diff --git a/lua/pending/init.lua b/lua/pending/init.lua index 4e093bf..06c722c 100644 --- a/lua/pending/init.lua +++ b/lua/pending/init.lua @@ -83,16 +83,6 @@ local function _save_and_notify() M._recompute_counts() end ----@return boolean -local function require_saved() - local bufnr = buffer.bufnr() - if bufnr and vim.bo[bufnr].modified then - log.warn('save changes first (:w)') - return false - end - return true -end - ---@return pending.Counts function M.counts() if not _counts then @@ -185,9 +175,6 @@ end ---@param pred_str string ---@return nil function M.filter(pred_str) - if not require_saved() then - return - end if pred_str == 'clear' or pred_str == '' then buffer.set_filter({}, {}) local bufnr = buffer.bufnr() @@ -256,9 +243,6 @@ function M._setup_buf_mappings(bufnr) M.toggle_complete() end, view = function() - if not require_saved() then - return - end buffer.toggle_view() end, priority = function() @@ -271,9 +255,6 @@ function M._setup_buf_mappings(bufnr) M.undo_write() end, filter = function() - if not require_saved() then - return - end vim.ui.input({ prompt = 'Filter: ' }, function(input) if input then M.filter(input) @@ -389,9 +370,6 @@ end ---@return nil function M.undo_write() - if not require_saved() then - return - end local s = get_store() local stack = s:undo_stack() if #stack == 0 then @@ -410,9 +388,6 @@ function M.toggle_complete() if not bufnr then return end - if not require_saved() then - return - end local row = vim.api.nvim_win_get_cursor(0)[1] local meta = buffer.meta() if not meta[row] or meta[row].type ~= 'task' then @@ -460,9 +435,6 @@ end function M.done(id_str) local id if not id_str or id_str == '' then - if not require_saved() then - return - end local row = vim.api.nvim_win_get_cursor(0)[1] local meta = buffer.meta() if not meta[row] or meta[row].type ~= 'task' then @@ -471,6 +443,7 @@ function M.done(id_str) end id = meta[row].id if not id then + log.error('Task has no ID — save the buffer first.') return end else @@ -520,9 +493,6 @@ function M.toggle_priority() if not bufnr then return end - if not require_saved() then - return - end local row = vim.api.nvim_win_get_cursor(0)[1] local meta = buffer.meta() if not meta[row] or meta[row].type ~= 'task' then @@ -555,9 +525,6 @@ function M.prompt_date() if not bufnr then return end - if not require_saved() then - return - end local row = vim.api.nvim_win_get_cursor(0)[1] local meta = buffer.meta() if not meta[row] or meta[row].type ~= 'task' then @@ -918,33 +885,22 @@ function M.edit(id_str, rest) log.info('Task #' .. id .. ' updated: ' .. table.concat(feedback, ', ')) end ----@param args? string ---@return nil -function M.auth(args) +function M.auth() local oauth = require('pending.sync.oauth') - local parts = {} - for w in (args or ''):gmatch('%S+') do - table.insert(parts, w) - end - local action = parts[#parts] - if action == parts[1] and (action == 'gtasks' or action == 'gcal') then - action = nil - end - - if action == 'clear' then - oauth.google_client:clear_tokens() - log.info('OAuth tokens cleared — run :Pending auth to re-authenticate.') - elseif action == 'reset' then - oauth.google_client:_wipe() - log.info('OAuth tokens and credentials cleared — run :Pending auth to set up from scratch.') - else + vim.ui.select({ 'Google Tasks', 'Google Calendar', 'Google Tasks and Google Calendar' }, { + prompt = 'Authenticate with:', + }, function(choice) + if not choice then + return + end local creds = oauth.google_client:resolve_credentials() if creds.client_id == oauth.BUNDLED_CLIENT_ID then oauth.google_client:setup() else oauth.google_client:auth() end - end + end) end ---@param args string @@ -963,7 +919,7 @@ function M.command(args) local id_str, edit_rest = rest:match('^(%S+)%s*(.*)') M.edit(id_str, edit_rest) elseif cmd == 'auth' then - M.auth(rest) + M.auth() elseif SYNC_BACKEND_SET[cmd] then local action = rest:match('^(%S+)') run_sync(cmd, action) diff --git a/lua/pending/sync/gcal.lua b/lua/pending/sync/gcal.lua index 1fe8557..942fbec 100644 --- a/lua/pending/sync/gcal.lua +++ b/lua/pending/sync/gcal.lua @@ -134,7 +134,16 @@ local function with_token(callback) oauth.async(function() local token = oauth.google_client:get_access_token() if not token then - log.warn('not authenticated — run :Pending auth') + oauth.google_client:auth(function() + oauth.async(function() + local fresh = oauth.google_client:get_access_token() + if fresh then + callback(fresh) + else + log.error(oauth.google_client.name .. ': authorization failed or was cancelled') + end + end) + end) return end callback(token) diff --git a/lua/pending/sync/gtasks.lua b/lua/pending/sync/gtasks.lua index 6c8bef3..9fc7459 100644 --- a/lua/pending/sync/gtasks.lua +++ b/lua/pending/sync/gtasks.lua @@ -404,7 +404,16 @@ local function with_token(callback) oauth.async(function() local token = oauth.google_client:get_access_token() if not token then - log.warn('not authenticated — run :Pending auth') + oauth.google_client:auth(function() + oauth.async(function() + local fresh = oauth.google_client:get_access_token() + if fresh then + callback(fresh) + else + log.error(oauth.google_client.name .. ': authorization failed or was cancelled') + end + end) + end) return end callback(token) diff --git a/lua/pending/sync/oauth.lua b/lua/pending/sync/oauth.lua index 8539ea6..224476b 100644 --- a/lua/pending/sync/oauth.lua +++ b/lua/pending/sync/oauth.lua @@ -496,11 +496,6 @@ function OAuthClient:_wipe() os.remove(vim.fn.stdpath('data') .. '/pending/google_credentials.json') end ----@return nil -function OAuthClient:clear_tokens() - os.remove(self:token_path()) -end - ---@param opts { name: string, scope: string, port: integer, config_key: string } ---@return pending.OAuthClient function M.new(opts) diff --git a/plugin/pending.lua b/plugin/pending.lua index e456f09..d246fba 100644 --- a/plugin/pending.lua +++ b/plugin/pending.lua @@ -213,21 +213,6 @@ end, { if cmd_line:match('^Pending%s+edit') then return complete_edit(arg_lead, cmd_line) end - if cmd_line:match('^Pending%s+auth') then - local after_auth = cmd_line:match('^Pending%s+auth%s+(.*)') or '' - local parts = {} - for w in after_auth:gmatch('%S+') do - table.insert(parts, w) - end - local trailing = after_auth:match('%s$') - if #parts == 0 or (#parts == 1 and not trailing) then - return filter_candidates(arg_lead, { 'gcal', 'gtasks', 'clear', 'reset' }) - end - if #parts == 1 or (#parts == 2 and not trailing) then - return filter_candidates(arg_lead, { 'clear', 'reset' }) - end - return {} - end local backend_set = pending.sync_backend_set() local matched_backend = cmd_line:match('^Pending%s+(%S+)') if matched_backend and backend_set[matched_backend] then