From afb9e65f8d7f54857751ef36828133ca6058626a Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Tue, 24 Feb 2026 23:14:32 -0500 Subject: [PATCH] refactor(views): adopt markdown checkbox line format Problem: task lines used an opaque /ID/ [N] prefix format that was hard to read and inconsistent between category and priority views. Header lines had no visual marker distinguishing them from tasks. Solution: render headers as '## Cat', task lines as '/ID/- [x|!| ] description'. State encoding: [x]=done, [!]=urgent, [ ]=pending. Both views use the same construction. --- lua/pending/views.lua | 12 +++++------- spec/views_spec.lua | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/lua/pending/views.lua b/lua/pending/views.lua index 84567e9..7bcfaca 100644 --- a/lua/pending/views.lua +++ b/lua/pending/views.lua @@ -125,7 +125,7 @@ function M.category_view(tasks) table.insert(lines, '') table.insert(meta, { type = 'blank' }) end - table.insert(lines, cat) + table.insert(lines, '## ' .. cat) table.insert(meta, { type = 'header', category = cat }) local all = {} @@ -138,9 +138,8 @@ function M.category_view(tasks) for _, task in ipairs(all) do local prefix = '/' .. task.id .. '/' - local indent = ' ' - local prio = task.priority > 0 and ('[' .. task.priority .. '] ') or '' - local line = prefix .. indent .. prio .. task.description + local state = task.status == 'done' and 'x' or (task.priority > 0 and '!' or ' ') + local line = prefix .. '- [' .. state .. '] ' .. task.description table.insert(lines, line) table.insert(meta, { type = 'task', @@ -189,9 +188,8 @@ function M.priority_view(tasks) for _, task in ipairs(all) do local prefix = '/' .. task.id .. '/' - local indent = ' ' - local prio = task.priority == 1 and '! ' or '' - local line = prefix .. indent .. prio .. task.description + local state = task.status == 'done' and 'x' or (task.priority > 0 and '!' or ' ') + local line = prefix .. '- [' .. state .. '] ' .. task.description table.insert(lines, line) table.insert(meta, { type = 'task', diff --git a/spec/views_spec.lua b/spec/views_spec.lua index 9ba12f9..4d91e06 100644 --- a/spec/views_spec.lua +++ b/spec/views_spec.lua @@ -27,7 +27,7 @@ describe('views', function() store.add({ description = 'Task A', category = 'Work' }) store.add({ description = 'Task B', category = 'Work' }) local lines, meta = views.category_view(store.active_tasks()) - assert.are.equal('Work', lines[1]) + assert.are.equal('## Work', lines[1]) assert.are.equal('header', meta[1].type) assert.is_true(lines[2]:find('Task A') ~= nil) assert.is_true(lines[3]:find('Task B') ~= nil) @@ -113,10 +113,10 @@ describe('views', function() task_line = lines[i] end end - assert.are.equal('/1/ My task', task_line) + assert.are.equal('/1/- [ ] My task', task_line) end) - it('formats priority task lines as /ID/ ! description', function() + it('formats priority task lines as /ID/- [!] description', function() store.add({ description = 'Important', category = 'Inbox', priority = 1 }) local lines, meta = views.category_view(store.active_tasks()) local task_line @@ -125,7 +125,7 @@ describe('views', function() task_line = lines[i] end end - assert.are.equal('/1/ ! Important', task_line) + assert.are.equal('/1/- [!] Important', task_line) end) it('sets LineMeta type=header for header lines with correct category', function() @@ -220,8 +220,8 @@ describe('views', function() end end end - assert.are.equal('Work', first_header) - assert.are.equal('Inbox', second_header) + assert.are.equal('## Work', first_header) + assert.are.equal('## Inbox', second_header) end) it('appends categories not in category_order after ordered ones', function() @@ -236,8 +236,8 @@ describe('views', function() table.insert(headers, lines[i]) end end - assert.are.equal('Work', headers[1]) - assert.are.equal('Errands', headers[2]) + assert.are.equal('## Work', headers[1]) + assert.are.equal('## Errands', headers[2]) end) it('preserves insertion order when category_order is empty', function() @@ -250,8 +250,8 @@ describe('views', function() table.insert(headers, lines[i]) end end - assert.are.equal('Alpha', headers[1]) - assert.are.equal('Beta', headers[2]) + assert.are.equal('## Alpha', headers[1]) + assert.are.equal('## Beta', headers[2]) end) end) @@ -325,10 +325,10 @@ describe('views', function() assert.is_true(earlier_row < later_row) end) - it('formats task lines as /ID/ description', function() + it('formats task lines as /ID/- [ ] description', function() store.add({ description = 'My task', category = 'Inbox' }) local lines, _ = views.priority_view(store.active_tasks()) - assert.are.equal('/1/ My task', lines[1]) + assert.are.equal('/1/- [ ] My task', lines[1]) end) it('sets show_category=true for all task meta entries', function()