@@ -357,12 +357,14 @@ end
357
357
function Headline :set_todo (keyword )
358
358
local todo , node = self :get_todo ()
359
359
if todo then
360
- return self :_set_node_text (node , keyword )
360
+ self :_set_node_text (node , keyword )
361
+ return self :update_parent_cookie_from_todo ()
361
362
end
362
363
363
364
local stars = self :_get_child_node (' stars' )
364
365
local _ , level = stars :end_ ()
365
- return self :_set_node_text (stars , (' %s %s' ):format ((' *' ):rep (level ), keyword ))
366
+ self :_set_node_text (stars , (' %s %s' ):format ((' *' ):rep (level ), keyword ))
367
+ return self :update_parent_cookie_from_todo ()
366
368
end
367
369
368
370
memoize (' get_todo' )
@@ -882,6 +884,14 @@ function Headline:remove_scheduled_date()
882
884
return self :_remove_date (' SCHEDULED' )
883
885
end
884
886
887
+ function Headline :update_parent_cookie_from_todo ()
888
+ local parent = self :get_parent_headline ()
889
+ if parent and parent .headline then
890
+ parent :update_cookie ()
891
+ end
892
+ return self
893
+ end
894
+
885
895
function Headline :get_cookie ()
886
896
local cookie = self :_parse_title_part (' %[%d*/%d*%]' )
887
897
if cookie then
@@ -891,37 +901,47 @@ function Headline:get_cookie()
891
901
end
892
902
893
903
function Headline :update_cookie ()
894
- local section = self :node ():parent ()
895
- if not section then
904
+ -- Return early if the headline doesn't have a cookie
905
+ local cookie = self :get_cookie ()
906
+ if not cookie then
896
907
return self
897
908
end
898
909
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
+ local num , denum = 0 , 0
911
+ -- Count checked boxes from all lists
912
+ local section = self :node ():parent ()
913
+ if section then
914
+ local body = section :field (' body' )[1 ]
915
+ if body then
916
+ for node in body :iter_children () do
917
+ if node :type () == ' list' then
918
+ local boxes = self :child_checkboxes (node )
919
+ denum = denum + # boxes
920
+ local checked_boxes = vim .tbl_filter (function (box )
921
+ return box :match (' %[%w%]' )
922
+ end , boxes )
923
+ num = num + # checked_boxes
924
+ end
925
+ end
910
926
end
911
927
end
912
928
929
+ -- Count done children headlines
930
+ local children = self :get_child_headlines ()
931
+ local dones = vim .tbl_filter (function (h )
932
+ return h :is_done ()
933
+ end , children )
934
+ num = num + # dones
935
+ denum = denum + # children
936
+
913
937
-- Update the cookie
914
- local cookie = self :get_cookie ()
915
- if cookie then
916
- local new_cookie_val
917
- if self .file :get_node_text (cookie ):find (' %%' ) then
918
- new_cookie_val = (' [%d%%]' ):format ((num_checked_boxes / num_boxes ) * 100 )
919
- else
920
- new_cookie_val = (' [%d/%d]' ):format (num_checked_boxes , num_boxes )
921
- end
922
- return self :_set_node_text (cookie , new_cookie_val )
938
+ local new_cookie_val
939
+ if self .file :get_node_text (cookie ):find (' %%' ) then
940
+ new_cookie_val = (' [%d%%]' ):format ((num / denum ) * 100 )
941
+ else
942
+ new_cookie_val = (' [%d/%d]' ):format (num , denum )
923
943
end
924
- return self
944
+ return self : _set_node_text ( cookie , new_cookie_val )
925
945
end
926
946
927
947
function Headline :child_checkboxes (list_node )
0 commit comments