1

Is there a way to show the number of items with a given tag(s) in a given subtree.

For example: I want the number of entries not in a done state

* Tasks (2) ** DONE done thing ** STARTED do thing ** TODO do another thing ** CANCELLED thing I don't have to do Edit: I know that you can you can use [/] to get TODO/TOTAL but I'm want the number of TODO not the total. Basically, I'm not interested in the total number of entries as it will increase infinitum. Alternatively, if it didn't include archive items that would work to

Stretch goal would be to adjust the colour of the number dependant on some range (i.e. 0-2 Green, 3-4, yellow, 5+ Red

Cheers

3
  • Aren't the brackets [/] in the headline exactly the tool for that? See: orgmode.org/manual/Breaking-down-tasks.html But, maybe, I don't fully understand what you want. In that case It would be good if you write in your question how your goal differs from what the brackets do.
    – Tobias
    Nov 24, 2017 at 5:24
  • I have updated with more information on what I'm trying to achieve
    – Dan Galipo
    Nov 26, 2017 at 21:47
  • I've added a version reaching your stretch-goal.
    – Tobias
    Nov 28, 2017 at 4:27

1 Answer 1

2

The following hook adds (2) to the todo cookie [3/4]. I.e., you get [3/4](2).

That should solve your problem at least partially. Note, that it is difficult to replace the todo cookie completely by the number of todo entries since the format of this cookie is used at many places to manage the todo statistics. The functions are not written modification-friendly. You would have to re-write a substantial part of org-mode.

(defun org-TODO-cookie (n-done n-not-done)
  "Add number of not done entries in org-headlines."
  (save-excursion
    (org-back-to-heading t)
    (while (re-search-forward "\\[[0-9]+\\(/[0-9]+\\|%\\)\\]" (line-end-position) t)
      (when (looking-at "([0-9]+)")
        (replace-match ""))
      (insert (format "(%d)" n-not-done)))))

(add-hook 'org-after-todo-statistics-hook #'org-TODO-cookie)

A version fulfilling your stretch-goal of coloring the todo cookies:

(defun org-TODO-cookie (n-done n-not-done)
  "Add number of not done entries in org-headlines."
  (save-excursion
    (org-back-to-heading t)
    (while (re-search-forward "\\[[0-9]+\\(/[0-9]+\\|%\\)\\]" (line-end-position) t)
      (when (looking-at "([0-9]+)")
        (replace-match ""))
      (insert (format "(%d)" n-not-done)))))

(add-hook 'org-after-todo-statistics-hook #'org-TODO-cookie)

(defun org-at-TODO-cookie (&optional _limit)
  "Non-nil if looking at a TODO cookie ([0-9]+)"
  (when (looking-at "(\\([0-9]+\\))")
    (goto-char (match-end 0))))

(defface org-attention          ;Copied from `font-lock-type-face'
  '((((class color) (min-colors 16) (background light)) (:foreground "yellow" :bold t))
    (((class color) (min-colors 16) (background dark)) (:foreground "yellow" :bold t))
    (((class color) (min-colors 8)) (:foreground "yellow"))
    (t (:bold t)))
  "Face used for todo keywords that indicate items that need attention."
  :group 'org-faces)

(defface org-checkbox-statistics-attention '((t (:inherit org-attention)))
  "Face used for finished checkbox statistics."
  :group 'org-faces)

(defcustom org-todo-todo-faces '((2 . org-checkbox-statistics-done)
                 (4 . org-checkbox-statistics-attention)
                 (5 . org-checkbox-statistics-todo))
  "Alist of limits for the fontification of todo cookies.
Each element is a cons of a limit and a face.
If the number of todo items is not greater than the limit face is used for fontification.
The largest limit always stands for infinity."
  :group 'org-todo
  :type '(repeat (cons number face)))

(defun org-get-TODO-cookie-face ()
  "Select the face for the TODO cookie.
See variable `org-todo-todo-faces'."
  (let* ((n-todo (string-to-number (match-string 1)))
     (limits (sort (mapcar #'car org-todo-todo-faces) #'<))
     (limit limits))
    (while (and (cdr limit)
        (> n-todo (car limit)))
      (setq limit (cdr limit)))
    (if limit
    (cdr (assoc (car limit) org-todo-todo-faces))
      'default)))

(defun org-font-lock-TODO-cookie-hook-fun ()
  "Install rule for fontification of todo cookies in `org-font-lock-keywords'."
  (let ((todo-stat-entry (assoc-string "\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]" org-font-lock-extra-keywords)))
    (when todo-stat-entry
      (setf (nthcdr 2 todo-stat-entry) '((org-at-TODO-cookie nil nil (0 (org-get-TODO-cookie-face) t)))))))

(add-hook 'org-font-lock-set-keywords-hook #'org-font-lock-TODO-cookie-hook-fun)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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