@@ -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 ()
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 ()
366
368
end
367
369
368
370
memoize (' get_todo' )
@@ -890,36 +892,74 @@ function Headline:get_cookie()
890
892
return self :_parse_title_part (' %[%d?%d?%d?%%%]' )
891
893
end
892
894
895
+ function Headline :_set_cookie (cookie , num , denum )
896
+ -- Update the cookie
897
+ local new_cookie_val
898
+ if self .file :get_node_text (cookie ):find (' %%' ) then
899
+ new_cookie_val = (' [%d%%]' ):format ((num / denum ) * 100 )
900
+ else
901
+ new_cookie_val = (' [%d/%d]' ):format (num , denum )
902
+ end
903
+ return self :_set_node_text (cookie , new_cookie_val )
904
+ end
905
+
893
906
function Headline :update_cookie ()
907
+ -- Update cookie state from a check box state change
908
+
909
+ -- Return early if the headline doesn't have a cookie
910
+ local cookie = self :get_cookie ()
911
+ if not cookie then
912
+ return self
913
+ end
914
+
894
915
local section = self :node ():parent ()
895
916
if not section then
896
917
return self
897
918
end
898
919
899
- -- Go through all the lists in this headline and gather checked_boxes
900
- local num_boxes , num_checked_boxes = 0 , 0
920
+ -- Count checked boxes from all lists
921
+ local num_checked_boxes , num_boxes = 0 , 0
901
922
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
923
+ if body then
924
+ for node in body :iter_children () do
925
+ if node :type () == ' list' then
926
+ local boxes = self :child_checkboxes (node )
927
+ num_boxes = num_boxes + # boxes
928
+ local checked_boxes = vim .tbl_filter (function (box )
929
+ return box :match (' %[%w%]' )
930
+ end , boxes )
931
+ num_checked_boxes = num_checked_boxes + # checked_boxes
932
+ end
910
933
end
911
934
end
912
935
913
- -- Update the cookie
936
+ -- Set the cookie
937
+ return self :_set_cookie (cookie , num_checked_boxes , num_boxes )
938
+ end
939
+
940
+ function Headline :update_todo_cookie ()
941
+ -- Update cookie state from a TODO state change
942
+
943
+ -- Return early if the headline doesn't have a cookie
914
944
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 )
945
+ if not cookie then
946
+ return self
947
+ end
948
+
949
+ -- Count done children headlines
950
+ local children = self :get_child_headlines ()
951
+ local dones = vim .tbl_filter (function (h )
952
+ return h :is_done ()
953
+ end , children )
954
+
955
+ -- Set the cookie
956
+ return self :_set_cookie (cookie , # dones , # children )
957
+ end
958
+
959
+ function Headline :update_parent_cookie ()
960
+ local parent = self :get_parent_headline ()
961
+ if parent and parent .headline then
962
+ parent :update_todo_cookie ()
923
963
end
924
964
return self
925
965
end
0 commit comments