Skip to content

Commit 22094c4

Browse files
authored
feat: support updating a headline's cookie from multiple lists (#925)
* Update cookies from multiple list * add a test
1 parent fb9580c commit 22094c4

File tree

3 files changed

+45
-8
lines changed

3 files changed

+45
-8
lines changed

lua/orgmode/files/elements/listitem.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function Listitem:update_checkbox(action)
7171
else
7272
local parent_headline = self.file:get_closest_headline_or_nil()
7373
if parent_headline then
74-
parent_headline:update_cookie(parent_list)
74+
parent_headline:update_cookie()
7575
end
7676
end
7777
end

lua/orgmode/files/headline.lua

+23-7
Original file line numberDiff line numberDiff line change
@@ -890,22 +890,38 @@ function Headline:get_cookie()
890890
return self:_parse_title_part('%[%d?%d?%d?%%%]')
891891
end
892892

893-
function Headline:update_cookie(list_node)
894-
local total_boxes = self:child_checkboxes(list_node)
895-
local checked_boxes = vim.tbl_filter(function(box)
896-
return box:match('%[%w%]')
897-
end, total_boxes)
893+
function Headline:update_cookie()
894+
local section = self:node():parent()
895+
if not section then
896+
return self
897+
end
898898

899+
-- Go through all the lists in this headline and gather checked_boxes
900+
local num_boxes, num_checked_boxes = 0, 0
901+
local body = section:field('body')[1]
902+
for node in body:iter_children() do
903+
if node:type() == 'list' then
904+
local boxes = self:child_checkboxes(node)
905+
num_boxes = num_boxes + #boxes
906+
local checked_boxes = vim.tbl_filter(function(box)
907+
return box:match('%[%w%]')
908+
end, boxes)
909+
num_checked_boxes = num_checked_boxes + #checked_boxes
910+
end
911+
end
912+
913+
-- Update the cookie
899914
local cookie = self:get_cookie()
900915
if cookie then
901916
local new_cookie_val
902917
if self.file:get_node_text(cookie):find('%%') then
903-
new_cookie_val = ('[%d%%]'):format((#checked_boxes / #total_boxes) * 100)
918+
new_cookie_val = ('[%d%%]'):format((num_checked_boxes / num_boxes) * 100)
904919
else
905-
new_cookie_val = ('[%d/%d]'):format(#checked_boxes, #total_boxes)
920+
new_cookie_val = ('[%d/%d]'):format(num_checked_boxes, num_boxes)
906921
end
907922
return self:_set_node_text(cookie, new_cookie_val)
908923
end
924+
return self
909925
end
910926

911927
function Headline:child_checkboxes(list_node)

tests/plenary/ui/mappings/checkbox_spec.lua

+21
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,25 @@ describe('Checkbox mappings', function()
151151
'- [ ] checkbox item',
152152
}, vim.api.nvim_buf_get_lines(0, 0, 6, false))
153153
end)
154+
155+
it('should update headline cookies from multiple lists', function()
156+
helpers.create_file({
157+
'* Test orgmode [/]',
158+
'First List',
159+
'- [ ] checkbox item',
160+
'- [ ] checkbox item',
161+
'Second List',
162+
'- [ ] checkbox item',
163+
})
164+
vim.fn.cursor(4, 1)
165+
vim.cmd([[exe "norm \<C-space>"]])
166+
assert.are.same({
167+
'* Test orgmode [1/3]',
168+
'First List',
169+
'- [ ] checkbox item',
170+
'- [X] checkbox item',
171+
'Second List',
172+
'- [ ] checkbox item',
173+
}, vim.api.nvim_buf_get_lines(0, 0, 6, false))
174+
end)
154175
end)

0 commit comments

Comments
 (0)