I have several tasks in my Org file, one of which has items starting with a checkbox (but only those). They all have a statistic cookie at their end ([n/m]).

I'm looking for a way to automatically update the parent task from TODO to DONE once all of the checkboxes are marked as done as well.

The documentation says:

If you would like a TODO entry to automatically change to DONE when all children are done, you can use the following setup [...]

Another possibility is the use of checkboxes to identify (a hierarchy of) a large number of subtasks (see Checkboxes).

The way I understand that last part is that if children items are checkboxes, parent state should already be automatically updated (which is not the case).

What am I missing?


From org-after-todo-statistics-hook's documentation (org.el):

Hook that is called after a TODO statistics cookie has been updated. Each function is called with two arguments: the number of not-done entries and the number of done entries.

Which means that the proposed code from orgmode.org:

(defun org-summary-todo (n-done n-not-done)
  "Switch entry to DONE when all subentries are done, to TODO otherwise."
  (let (org-log-done org-log-states)   ; turn off logging
    (org-todo (if (= n-not-done 0) "DONE" "TODO"))))

(add-hook 'org-after-todo-statistics-hook 'org-summary-todo)

won't count checkbox items.

  • Do you have a statistics cookie in the headline? Like this: * Heading [0/1] – erikstokes Jan 26 '16 at 14:27
  • Yes, there is. Forgot to mention that bit my bad. – Mathieu Marques Jan 26 '16 at 14:30
  • 1
    I think this misunderstanding comes from the org manual not being so clear in this case. The line that starts "Another possibility is the use of checkboxes..." is a new paragraph under the heading "Breaking tasks down into subtasks". I think that "another possibility" in this case is referring to another possibility for breaking tasks into subtasks not another possibility for automatically changing the TODO state. Maybe try their suggested function and hook (though I couldn't get this to wokr) – elethan Jan 26 '16 at 15:09
  • @elethan It actually makes sense, I guess. Yes see my edit :) – Mathieu Marques Jan 26 '16 at 15:26
  • This is a FAQ. – NickD Feb 11 at 19:17

As you mentioned in your updated question, org-after-todo-statistics-hook isn't what you want. What you want is org-checkbox-statistics-hook.

I use this function to do what you describe (they should really get this functionality into org-mode):

(defun my/org-checkbox-todo ()
  "Switch header TODO state to DONE when all checkboxes are ticked, to TODO otherwise"
  (let ((todo-state (org-get-todo-state)) beg end)
    (unless (not todo-state)
    (org-back-to-heading t)
    (setq beg (point))
    (setq end (point))
    (goto-char beg)
    (if (re-search-forward "\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
                   end t)
        (if (match-end 1)
        (if (equal (match-string 1) "100%")
            (unless (string-equal todo-state "DONE")
              (org-todo 'done))
          (unless (string-equal todo-state "TODO")
            (org-todo 'todo)))
          (if (and (> (match-end 2) (match-beginning 2))
               (equal (match-string 2) (match-string 3)))
          (unless (string-equal todo-state "DONE")
            (org-todo 'done))
        (unless (string-equal todo-state "TODO")
          (org-todo 'todo)))))))))

(add-hook 'org-checkbox-statistics-hook 'my/org-checkbox-todo) will it call it every time you toggle a checkbox.

It does require you have a statistics cookie (the thing you get with [/] or [%] then C-c C-c) in the header.

  • 1
    Do you happen to have a version that, when the TODO is scheduled to repeat, unchecks the checklist for the scheduling again? :) – ctietze May 16 '18 at 17:40

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.