Hi Bastien and Ihor,

Thank you for the discussion and confirmation.

Attached is the patch implementing the agreed renames:

- `org-checkbox-hierarchical-statistics' to
  `org-checkbox-children-only-statistics'
- `org-hierarchical-todo-statistics' to
  `org-todo-children-only-statistics'

The old names remain available as obsolete variable aliases, and the
existing polarity and behavior are unchanged.

The patch also updates all uses, the manual, ORG-NEWS, and the relevant
tests.  The tests additionally verify that the obsolete names resolve
to the new variables.

Best,
-- 
Slawomir Grochowski
>From 61094d787470f3b8c50b31eca5efd45851a77141 Mon Sep 17 00:00:00 2001
From: Slawomir Grochowski <[email protected]>
Date: Tue, 28 Jul 2026 20:50:04 +0200
Subject: [PATCH] org: Rename statistics scope options

* lisp/org-list.el (org-checkbox-direct-children-statistics):
Rename from `org-checkbox-hierarchical-statistics'.  Update uses.
* lisp/org.el (org-todo-direct-children-statistics): Rename from
`org-hierarchical-todo-statistics'.
(org-update-parent-todo-statistics): Use the new name.
* lisp/org-compat.el (org-checkbox-hierarchical-statistics)
(org-hierarchical-todo-statistics): Define obsolete aliases.
* testing/lisp/test-org-list.el
(test-org-list/update-checkbox-count): Test the obsolete alias and use
the new checkbox option.
* testing/lisp/test-org.el
(test-org/update-todo-statistics-cookies): Test the obsolete alias and
direct-children and recursive collection scopes.
* doc/org-manual.org: Document the new option names.
* etc/ORG-NEWS: Announce the renames.

Refactoring: Rename Variable.

No behavior change.
---
 doc/org-manual.org            | 20 ++++++++++----------
 etc/ORG-NEWS                  |  9 +++++++++
 lisp/org-compat.el            |  4 ++++
 lisp/org-list.el              |  4 ++--
 lisp/org.el                   |  8 ++++----
 testing/lisp/test-org-list.el | 13 ++++++++-----
 testing/lisp/test-org.el      | 19 ++++++++++++++++++-
 7 files changed, 55 insertions(+), 22 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index cd8903a7e..c8c4ca151 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -4711,12 +4711,12 @@ If a heading has both checkboxes and TODO children below it, the
 meaning of the statistics cookie becomes ambiguous.  Set the property
 =COOKIE_DATA= to either =checkbox= or =todo= to resolve this issue.
 
-#+vindex: org-hierarchical-todo-statistics
+#+vindex: org-todo-direct-children-statistics
 If you would like to have the statistics cookie count any TODO entries
-in the subtree (not just direct children), configure the variable
-~org-hierarchical-todo-statistics~.  To do this for a single subtree,
-include the word =recursive= into the value of the =COOKIE_DATA=
-property.
+in the subtree (not just direct children), set
+~org-todo-direct-children-statistics~ to nil.  To do this for a single
+subtree, include the word =recursive= into the value of the
+=COOKIE_DATA= property.
 
 #+begin_example
 ,* Parent capturing statistics [2/20]
@@ -4770,7 +4770,7 @@ Here is an example of a checkbox list.
 #+cindex: statistics, for checkboxes
 #+cindex: checkbox statistics
 #+cindex: @samp{COOKIE_DATA}, property
-#+vindex: org-checkbox-hierarchical-statistics
+#+vindex: org-checkbox-direct-children-statistics
 The =[2/4]= and =[1/3]= in the first and second line are cookies
 indicating how many of the checkboxes present in this entry have been checked
 off, and the total number of checkboxes present.  This can give you an
@@ -4778,10 +4778,10 @@ idea of how many checkboxes remain, even without opening a folded
 entry.  The cookies can be placed into a headline or into (the first
 line of) a plain list item.  Each cookie covers checkboxes of direct
 children structurally below the headline/item on which the cookie
-appears[fn:: Set the variable ~org-checkbox-hierarchical-statistics~
-if you want such cookies to count all checkboxes below the cookie, not
-just those belonging to direct children.].  You have to insert the
-cookie yourself by typing either =[/]= or =[%]=.  With =[/]= you get
+appears[fn:: Set the variable ~org-checkbox-direct-children-statistics~
+to nil if you want such cookies to count all checkboxes below the
+cookie, not just those belonging to direct children.].  You have to
+insert the cookie yourself by typing either =[/]= or =[%]=.  With =[/]= you get
 an =n out of m= result, as in the examples above.  With =[%]= you get
 information about the percentage of checkboxes checked (in the above
 example, this would be =[50%]= and =[33%]=, respectively).  In a
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index bb965c02a..c0b972e2f 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -262,6 +262,15 @@ cookie =[N%]=.
 
 ** Removed or renamed functions and variables
 
+*** Statistics scope options have been renamed
+
+~org-checkbox-hierarchical-statistics~ is renamed to
+~org-checkbox-direct-children-statistics~, and
+~org-hierarchical-todo-statistics~ is renamed to
+~org-todo-direct-children-statistics~.  The new names describe the
+non-nil behavior explicitly.  The old names remain available as
+obsolete variable aliases.
+
 *** ~org-babel-remote-temporary-directory~ is now obsolete
 
 Org babel now allows TRAMP to determine the best temporary directory.
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index 55a4e481e..4a35ec022 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -552,6 +552,10 @@ Counting starts at 1."
 (define-obsolete-function-alias 'org-string-match-p 'string-match-p "9.0")
 
 ;;;; Functions and variables from previous releases now obsolete.
+(define-obsolete-variable-alias 'org-checkbox-hierarchical-statistics
+  'org-checkbox-direct-children-statistics "Org 10.0")
+(define-obsolete-variable-alias 'org-hierarchical-todo-statistics
+  'org-todo-direct-children-statistics "Org 10.0")
 (define-obsolete-variable-alias 'org-edit-src-content-indentation
   'org-src-content-indentation "Org 9.8")
 (define-obsolete-variable-alias 'org-export-ignored-local-variables
diff --git a/lisp/org-list.el b/lisp/org-list.el
index 8df83663c..ea09bf200 100644
--- a/lisp/org-list.el
+++ b/lisp/org-list.el
@@ -335,7 +335,7 @@ This hook runs even if checkbox rule in
 implement alternative ways of collecting statistics
 information.")
 
-(defcustom org-checkbox-hierarchical-statistics t
+(defcustom org-checkbox-direct-children-statistics t
   "Non-nil means checkbox statistics counts only the state of direct children.
 When nil, all boxes below the cookie are counted.
 This can be set to nil on a per-node basis using a COOKIE_DATA property
@@ -2593,7 +2593,7 @@ portion of the buffer."
 				          (save-match-data (org-element-context))))
                  (cookie-data (save-match-data (or (org-entry-get nil "COOKIE_DATA") "")))
 	         (recursivep
-	          (or (not org-checkbox-hierarchical-statistics)
+	          (or (not org-checkbox-direct-children-statistics)
 	              (string-match-p "\\<recursive\\>" cookie-data))))
 	    (when (and (org-element-type-p context 'statistics-cookie)
                        (not (string-match-p "\\<todo\\>" cookie-data)))
diff --git a/lisp/org.el b/lisp/org.el
index 294a5eb52..d7de04bcb 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -2082,7 +2082,7 @@ current entry each time a todo state is changed."
 		(repeat (string :tag "DONE keyword")))
 	  (other :tag "No TODO statistics" nil)))
 
-(defcustom org-hierarchical-todo-statistics t
+(defcustom org-todo-direct-children-statistics t
   "Non-nil means TODO statistics covers just direct children.
 When nil, all entries in the subtree are considered.
 This has only an effect if `org-provide-todo-statistics' is set.
@@ -10117,13 +10117,13 @@ respect narrowing."
 (defvar org-entry-property-inherited-from) ;; defined below
 (defun org-update-parent-todo-statistics ()
   "Update any statistics cookie in the parent of the current headline.
-When `org-hierarchical-todo-statistics' is nil, statistics will cover
+When `org-todo-direct-children-statistics' is nil, statistics will cover
 the entire subtree and this will travel up the hierarchy and update
 statistics everywhere."
   (let* ((prop (save-excursion
                  (org-up-heading-safe)
 		 (org-entry-get nil "COOKIE_DATA" 'inherit)))
-	 (recursive (or (not org-hierarchical-todo-statistics)
+	 (recursive (or (not org-todo-direct-children-statistics)
 			(and prop (string-match "\\<recursive\\>" prop))))
 	 (lim (or (and prop (marker-position org-entry-property-inherited-from))
 		  0))
@@ -10138,7 +10138,7 @@ statistics everywhere."
 	(setq ltoggle (funcall outline-level))
 	;; Three situations are to consider:
 
-	;; 1. if `org-hierarchical-todo-statistics' is nil, repeat up
+	;; 1. if `org-todo-direct-children-statistics' is nil, repeat up
 	;;    to the top-level ancestor on the headline;
 
 	;; 2. If parent has "recursive" property, repeat up to the
diff --git a/testing/lisp/test-org-list.el b/testing/lisp/test-org-list.el
index 1da621143..c1d034c2c 100644
--- a/testing/lisp/test-org-list.el
+++ b/testing/lisp/test-org-list.el
@@ -1129,6 +1129,9 @@ b. Item 2<point>"
 
 (ert-deftest test-org-list/update-checkbox-count ()
   "Test `org-update-checkbox-count' specifications."
+  (should
+   (eq (indirect-variable 'org-checkbox-hierarchical-statistics)
+       'org-checkbox-direct-children-statistics))
   ;; From a headline.
   (should
    (string-match "\\[0/1\\]"
@@ -1167,13 +1170,13 @@ b. Item 2<point>"
     (org-test-with-temp-text "- [ ] item 1\n- [ ] item 2 [/]\n  - [X] sub 1"
       (org-update-checkbox-count)
       (buffer-string))))
-  ;; Count do not apply to sub-lists unless count is not hierarchical.
-  ;; This state can be achieved with COOKIE_DATA node property set to
-  ;; "recursive".
+  ;; Do not count checkboxes in nested sub-lists unless collection is
+  ;; recursive.  Recursive collection can also be enabled with COOKIE_DATA
+  ;; node property set to "recursive".
   (should
    (string-match "\\[1/1\\]"
 		 (org-test-with-temp-text "- [/]\n  - item\n    - [X] sub-item"
-		   (let ((org-checkbox-hierarchical-statistics nil))
+		   (let ((org-checkbox-direct-children-statistics nil))
 		     (org-update-checkbox-count))
 		   (buffer-string))))
   (should
@@ -1210,7 +1213,7 @@ b. Item 2<point>"
     - [X] item
     :END:
   - [X] item2"
-		   (let ((org-checkbox-hierarchical-statistics nil))
+		   (let ((org-checkbox-direct-children-statistics nil))
 		     (org-update-checkbox-count))
 		   (buffer-string))))
   (let ((checklist (concat "- [%]\n"          ; 0/101 = 0%
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 9e9be9ebc..c8bdd14ed 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -4315,6 +4315,9 @@ text"
 
 (ert-deftest test-org/update-todo-statistics-cookies ()
   "Test updating TODO statistics cookies."
+  (should
+   (eq (indirect-variable 'org-hierarchical-todo-statistics)
+       'org-todo-direct-children-statistics))
   (let ((N 3)
         (parent "* [/]"))
     (dolist (n (number-sequence 0 N))
@@ -4369,7 +4372,21 @@ text"
       (should (string-match match
                             (org-test-with-temp-text tree
                               (org-update-statistics-cookies t)
-                              (buffer-string)))))))
+                              (buffer-string))))))
+  ;; Collect TODO statistics from direct children by default and from the
+  ;; entire subtree when requested.
+  (let ((tree "* Parent [/]\n** TODO Child\n*** DONE Grandchild"))
+    (should
+     (string-match "\\[0/1\\]"
+                   (org-test-with-temp-text tree
+                     (org-update-statistics-cookies t)
+                     (buffer-string))))
+    (should
+     (string-match "\\[1/2\\]"
+                   (let ((org-todo-direct-children-statistics nil))
+                     (org-test-with-temp-text tree
+                       (org-update-statistics-cookies t)
+                       (buffer-string)))))))
 
 ;;; Navigation
 
-- 
2.39.5

Reply via email to