From 23ae390f23ba12702ba42c4bbbaccd696ddfda86 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Fri, 6 Mar 2026 11:49:37 -0500 Subject: [PATCH] feat(init): warn on dirty buffer before store-dependent actions Problem: `toggle_complete`, `toggle_priority`, `prompt_date`, and `done` (no-args) all read from `buffer.meta()` which is stale whenever the buffer has unsaved edits, leading to silent no-ops or acting on the wrong task. Solution: Add a `require_saved()` guard that emits a `log.warn` and returns false when the buffer is modified. Each store-dependent action calls it before touching meta or the store. --- lua/pending/init.lua | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lua/pending/init.lua b/lua/pending/init.lua index 06c722c..d25b100 100644 --- a/lua/pending/init.lua +++ b/lua/pending/init.lua @@ -83,6 +83,16 @@ 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('Unsaved changes — :w first.') + return false + end + return true +end + ---@return pending.Counts function M.counts() if not _counts then @@ -388,6 +398,9 @@ 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 @@ -435,6 +448,9 @@ 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 @@ -443,7 +459,6 @@ 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 @@ -493,6 +508,9 @@ 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 @@ -525,6 +543,9 @@ 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