emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* after-todo-statistics hook for checkboxes
@ 2014-10-15 11:08 James Harkins
  2014-10-15 13:38 ` James Harkins
  0 siblings, 1 reply; 10+ messages in thread
From: James Harkins @ 2014-10-15 11:08 UTC (permalink / raw)
  To: orgmode

org-after-todo-statistics-hook allows you to do something to a node after its statistics cookie got updated. Unfortunately, it does this only for TODO subheadings and it doesn't work with checkboxes.

Use case: Grading assignments. Each assignment is a subheading. Each student's work for that assignment is a plain list item with a checkbox. When I finish grading one of them, I tick off the checkbox. At this point, I want the heading's TODO status to change:

- If all items are complete, change it to DONE.
- If there exist both finished and unfinished list items, change it to INPROG.
- If all items are still open, change it to TODO. (This could happen if I mistakenly ticked a checkbox and then un-ticked it.)

This should then cascade upward to the parent's statistics, all the way to the top level, so I can see at a glance (even with all top-level trees folded) that there is something remaining to grade.

I don't want to use subheadings for each student's work, because then my TODO agenda views will get cluttered with multiple entries per assignment.

Actually... after a little more poking around, the problem seems to be that org-update-checkbox-count refers to no hooks whatsoever. Should it go toward the end, here? (Untested.)

      (mapc (lambda (cookie)
	      (let* ((beg (car cookie))
		     (end (nth 1 cookie))
		     (percentp (nth 2 cookie))
		     (checked (car (nth 3 cookie)))
		     (total (cdr (nth 3 cookie)))
		     (new (if percentp
			      (format "[%d%%]" (/ (* 100 checked)
						  (max 1 total)))
			    (format "[%d/%d]" checked total))))
		(goto-char beg)
		(insert new)
		(delete-region (point) (+ (point) (- end beg)))
		(run-hook-with-args 'org-after-todo-statistics-hook
				    checked (- total checked))
		(when org-auto-align-tags (org-fix-tags-on-the-fly))))
	    cookies-list))))

hjh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: after-todo-statistics hook for checkboxes
  2014-10-15 11:08 after-todo-statistics hook for checkboxes James Harkins
@ 2014-10-15 13:38 ` James Harkins
  2014-10-15 13:45   ` Nicolas Goaziou
  0 siblings, 1 reply; 10+ messages in thread
From: James Harkins @ 2014-10-15 13:38 UTC (permalink / raw)
  To: orgmode

[-- Attachment #1: Type: text/plain, Size: 1990 bytes --]

On Wed, 15 Oct 2014 19:08:31 +0800
James Harkins <jamshark70@qq.com> wrote:

> org-after-todo-statistics-hook allows you to do something to a node after its statistics cookie got updated. Unfortunately, it does this only for TODO subheadings and it doesn't work with checkboxes.
> (snip)
> Actually... after a little more poking around, the problem seems to be that org-update-checkbox-count refers to no hooks whatsoever. Should it go toward the end, here? (Untested.)
> 
>       (mapc (lambda (cookie)
> 	      (let* ((beg (car cookie))
> 		     (end (nth 1 cookie))
> 		     (percentp (nth 2 cookie))
> 		     (checked (car (nth 3 cookie)))
> 		     (total (cdr (nth 3 cookie)))
> 		     (new (if percentp
> 			      (format "[%d%%]" (/ (* 100 checked)
> 						  (max 1 total)))
> 			    (format "[%d/%d]" checked total))))
> 		(goto-char beg)
> 		(insert new)
> 		(delete-region (point) (+ (point) (- end beg)))
> 		(run-hook-with-args 'org-after-todo-statistics-hook
> 				    checked (- total checked))
> 		(when org-auto-align-tags (org-fix-tags-on-the-fly))))
> 	    cookies-list))))

After dinner, I tested the change that I had speculated about, and... it works exactly correctly.

* TODO Test A [0/2]
** TODO Test B [0/2]
   - [ ] 1
   - [ ] 2
** TODO Test C

C-c C-c on "1" (with my hook function[1]):

* TODO Test A [0/2]
** INPROG Test B [1/2]
   - [X] 1
   - [ ] 2
** TODO Test C

C-c C-c on "2":

* INPROG Test A [1/2]
** DONE Test B [2/2]
   - [X] 1
   - [X] 2
** TODO Test C

So I'm submitting this as a TINYCHANGE patch. Do with it as you will, although I will keep using it locally until something better comes along.

hjh

[1]
(defun hjh-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"
         (if (= n-done 0) "TODO" "INPROG")))))

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

[-- Attachment #2: 0001-Run-org-after-todo-statistics-hook-when-toggling-a-c.patch --]
[-- Type: text/x-patch, Size: 902 bytes --]

From cbb4c589b1ed65152485ea2b687eb54ff7e2e478 Mon Sep 17 00:00:00 2001
From: James Harkins <jamshark70@dewdrop-world.net>
Date: Wed, 15 Oct 2014 21:32:28 +0800
Subject: [PATCH] Run org-after-todo-statistics-hook when toggling a checkbox

* org-list.el (org-update-checkbox-count): Run
org-after-todo-statistics-hook for each affected cookie.

TINYCHANGE
---
 lisp/org-list.el |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/lisp/org-list.el b/lisp/org-list.el
index b1d47c9..2fdda6b 100644
--- a/lisp/org-list.el
+++ b/lisp/org-list.el
@@ -2553,6 +2553,8 @@ With optional prefix argument ALL, do this for the whole buffer."
 		(goto-char beg)
 		(insert new)
 		(delete-region (point) (+ (point) (- end beg)))
+		(run-hook-with-args 'org-after-todo-statistics-hook
+				checked (- total checked))
 		(when org-auto-align-tags (org-fix-tags-on-the-fly))))
 	    cookies-list))))
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: after-todo-statistics hook for checkboxes
  2014-10-15 13:38 ` James Harkins
@ 2014-10-15 13:45   ` Nicolas Goaziou
       [not found]     ` <1491661ce88.27cd.0bb60a3c7e492ea180363c67eb170725@qq.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Goaziou @ 2014-10-15 13:45 UTC (permalink / raw)
  To: James Harkins; +Cc: orgmode

Hello,

James Harkins <jamshark70@qq.com> writes:

> On Wed, 15 Oct 2014 19:08:31 +0800
> James Harkins <jamshark70@qq.com> wrote:
>
>> org-after-todo-statistics-hook allows you to do something to a node after its statistics cookie got updated. Unfortunately, it does this only for TODO subheadings and it doesn't work with checkboxes.
>> (snip)
>> Actually... after a little more poking around, the problem seems to be that org-update-checkbox-count refers to no hooks whatsoever. Should it go toward the end, here? (Untested.)
>> 
>>       (mapc (lambda (cookie)
>> 	      (let* ((beg (car cookie))
>> 		     (end (nth 1 cookie))
>> 		     (percentp (nth 2 cookie))
>> 		     (checked (car (nth 3 cookie)))
>> 		     (total (cdr (nth 3 cookie)))
>> 		     (new (if percentp
>> 			      (format "[%d%%]" (/ (* 100 checked)
>> 						  (max 1 total)))
>> 			    (format "[%d/%d]" checked total))))
>> 		(goto-char beg)
>> 		(insert new)
>> 		(delete-region (point) (+ (point) (- end beg)))
>> 		(run-hook-with-args 'org-after-todo-statistics-hook
>> 				    checked (- total checked))
>> 		(when org-auto-align-tags (org-fix-tags-on-the-fly))))
>> 	    cookies-list))))
>
> After dinner, I tested the change that I had speculated about, and... it works exactly correctly.
>
> * TODO Test A [0/2]
> ** TODO Test B [0/2]
>    - [ ] 1
>    - [ ] 2
> ** TODO Test C
>
> C-c C-c on "1" (with my hook function[1]):
>
> * TODO Test A [0/2]
> ** INPROG Test B [1/2]
>    - [X] 1
>    - [ ] 2
> ** TODO Test C
>
> C-c C-c on "2":
>
> * INPROG Test A [1/2]
> ** DONE Test B [2/2]
>    - [X] 1
>    - [X] 2
> ** TODO Test C
>
> So I'm submitting this as a TINYCHANGE patch. Do with it as you will, although I will keep using it locally until something better comes along.
>
> hjh
>
> [1]
> (defun hjh-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"
>          (if (= n-done 0) "TODO" "INPROG")))))
>
> (add-hook 'org-after-todo-statistics-hook 'hjh-org-summary-todo)

See also "org-checklist.el" in contrib/.


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: after-todo-statistics hook for checkboxes
       [not found]     ` <1491661ce88.27cd.0bb60a3c7e492ea180363c67eb170725@qq.com>
@ 2014-10-16  1:01       ` James Harkins
  2014-10-16 16:39         ` Nicolas Goaziou
  0 siblings, 1 reply; 10+ messages in thread
From: James Harkins @ 2014-10-16  1:01 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode

On October 15, 2014 9:45:32 PM Nicolas Goaziou <mail@nicolasgoaziou.fr> wrote:

> See also "org-checklist.el" in contrib/.

Ok, I'll have a look. Not at my computer now.

I do think this issue qualifies as a bug (albeit minor). The real behavior 
deviates from the documentation (in a way that's difficult to justify 
logically). IMO it should be fixed, or the documentation should explain 
that the after todo statistics hook doesn't work for checkboxes without 
"require"ing org-checklist.

hjh

Sent with AquaMail for Android
http://www.aqua-mail.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: after-todo-statistics hook for checkboxes
  2014-10-16  1:01       ` James Harkins
@ 2014-10-16 16:39         ` Nicolas Goaziou
  2014-10-16 23:23           ` James Harkins
  0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Goaziou @ 2014-10-16 16:39 UTC (permalink / raw)
  To: James Harkins; +Cc: emacs-orgmode

James Harkins <jamshark70@qq.com> writes:

> I do think this issue qualifies as a bug (albeit minor). The real
> behavior deviates from the documentation (in a way that's difficult to
> justify logically). IMO it should be fixed, or the documentation
> should explain that the after todo statistics hook doesn't work for
> checkboxes without "require"ing org-checklist.

Using "org-checklist.el" was just a suggestion.
`org-todo-statistics-hook' is used for TODO (i.e. headlines) and
`org-checkbox-statistics-hook' is used for checkboxes (i.e. lists).
I see no bug here (although they aren't called with the same arguments,
but that's another story).


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: after-todo-statistics hook for checkboxes
  2014-10-16 16:39         ` Nicolas Goaziou
@ 2014-10-16 23:23           ` James Harkins
  2014-10-17 20:22             ` Nicolas Goaziou
  0 siblings, 1 reply; 10+ messages in thread
From: James Harkins @ 2014-10-16 23:23 UTC (permalink / raw)
  To: emacs-orgmode

At Thu, 16 Oct 2014 18:39:46 +0200,
Nicolas Goaziou wrote:
> `org-todo-statistics-hook' is used for TODO (i.e. headlines) and
> `org-checkbox-statistics-hook' is used for checkboxes (i.e. lists).
> I see no bug here (although they aren't called with the same arguments,
> but that's another story).

I'm sorry to be a pest, but I did get sent on a wild goose chase by what is either a/ faulty behavior or b/ a faulty docstring. The docstring of org-after-todo-statistics-hook says: "Hook that is called after a TODO statistics cookie has been updated." Well, that isn't true. Changing a checkbox updates a stats cookie, and the hook is *not* called. And it took more than an hour to figure that out. So, for the sake of users dealing with this in the future, let's at least fix the docstring then.

It isn't clear to me how to use org-checkbox-statistics-hook or org-todo-statistics-hook for my use case. This isn't about "alternative ways of collecting statistics" (org-checkbox-statistics-hook's docstring). I'm willing to switch to that, but less willing to trawl through the org sources (again) to figure it out. At least, not today.

hjh

For reference, from http://orgmode.org/worg/doc.html#hooks:

org-checkbox-statistics-hook nil

Hook that is run whenever Org thinks checkbox statistics should be updated.
This hook runs even if checkbox rule in
`org-list-automatic-rules' does not apply, so it can be used to
implement alternative ways of collecting statistics
information.


org-todo-statistics-hook nil

Hook that is run whenever Org thinks TODO statistics should be updated.
This hook runs even if there is no statistics cookie present, in which case
`org-after-todo-statistics-hook' would not run.


org-after-todo-statistics-hook nil

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.

For example, the following function, when added to this hook, will switch
an entry to DONE when all children are done, and back to TODO when new
entries are set to a TODO status.  Note that this hook is only called
when there is a statistics cookie in the headline!

 (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"))))

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: after-todo-statistics hook for checkboxes
  2014-10-16 23:23           ` James Harkins
@ 2014-10-17 20:22             ` Nicolas Goaziou
  2014-10-18  2:21               ` James Harkins
  0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Goaziou @ 2014-10-17 20:22 UTC (permalink / raw)
  To: James Harkins; +Cc: emacs-orgmode

Hello,

James Harkins <jamshark70@qq.com> writes:

> I'm sorry to be a pest, but I did get sent on a wild goose chase by
> what is either a/ faulty behavior or b/ a faulty docstring. The
> docstring of org-after-todo-statistics-hook says: "Hook that is called
> after a TODO statistics cookie has been updated." Well, that isn't
> true. Changing a checkbox updates a stats cookie, and the hook is
> *not* called.

This is because checkboxes (plain lists) are not related to TODO
keywords (headlines). There are TODO statistics cookies and checkbox
statistics cookies. Only the former run a hook once updated.

> And it took more than an hour to figure that out. So,
> for the sake of users dealing with this in the future, let's at least
> fix the docstring then.

Please provide a patch if you think a docstring can be improved.


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: after-todo-statistics hook for checkboxes
  2014-10-17 20:22             ` Nicolas Goaziou
@ 2014-10-18  2:21               ` James Harkins
  2014-10-18  7:31                 ` Nicolas Goaziou
  0 siblings, 1 reply; 10+ messages in thread
From: James Harkins @ 2014-10-18  2:21 UTC (permalink / raw)
  To: Nicolas Goaziou, emacs-orgmode

At Fri, 17 Oct 2014 22:22:20 +0200,
Nicolas Goaziou wrote:
> This is because checkboxes (plain lists) are not related to TODO
> keywords (headlines). There are TODO statistics cookies and checkbox
> statistics cookies. Only the former run a hook once updated.

Thanks for clarifying. I hadn't understood that distinction.

It occurred to me, after I sent my last e-mail, that someone might want one action after updating todo statistics and a different action after updating checkbox statistics. Using the same hook for both wouldn't be correct in that case.

So let me update my issue report/feature request:

-- If there is a hook to do something after updating todo statistics, then it would make sense to have a hook for updating checkbox statistics as well. That hook should be called with the same arguments (n-done n-not-done) so that the user could use one function for both, if desired.

I can do this pretty easily and update the documentation. I don't have FSF papers signed, but I'm willing to get that ball rolling as well.

But before spending any time on that, I want to ask if this is okay. I understand the objection against pressing org-after-todo-statistics-hook into service for checkboxes. If there's an objection against simply *having* a hook for checkboxes, I'm afraid I don't understand that.

Thanks for your patience,
hjh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: after-todo-statistics hook for checkboxes
  2014-10-18  2:21               ` James Harkins
@ 2014-10-18  7:31                 ` Nicolas Goaziou
  2014-10-20 12:46                   ` Bastien
  0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Goaziou @ 2014-10-18  7:31 UTC (permalink / raw)
  To: James Harkins; +Cc: emacs-orgmode

James Harkins <jamshark70@qq.com> writes:

> So let me update my issue report/feature request:
>
> -- If there is a hook to do something after updating todo statistics,
> then it would make sense to have a hook for updating checkbox
> statistics as well. That hook should be called with the same arguments
> (n-done n-not-done) so that the user could use one function for both,
> if desired.
>
> I can do this pretty easily and update the documentation. I don't have
> FSF papers signed, but I'm willing to get that ball rolling as well.
>
> But before spending any time on that, I want to ask if this is okay.
> I understand the objection against pressing
> org-after-todo-statistics-hook into service for checkboxes. If there's
> an objection against simply *having* a hook for checkboxes, I'm afraid
> I don't understand that.

I have no objection to this.

Note that this hook can be tricky to use because checkboxes are local to
the list. So adding a global effect to it (e.g., switching TODO state)
will sometimes fail. In the following example

  * Headline
  - [X] list1:item 1
  - [ ] list1:item 2

  Paragraph

  - [ ] list2:item 1
  - [ ] list2:item 2

checking "list1:item 2" will trigger the hook with (2 2) as arguments,
which may be surprising. I suggest to add a word of warning in the
documentation.

Thanks for working on it.


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: after-todo-statistics hook for checkboxes
  2014-10-18  7:31                 ` Nicolas Goaziou
@ 2014-10-20 12:46                   ` Bastien
  0 siblings, 0 replies; 10+ messages in thread
From: Bastien @ 2014-10-20 12:46 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode, James Harkins

Hi James and Nicolas,

Nicolas Goaziou <mail@nicolasgoaziou.fr> writes:

> I have no objection to this.

FWIW, same here.

> Thanks for working on it.

+1!

-- 
 Bastien

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-10-20 12:46 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-15 11:08 after-todo-statistics hook for checkboxes James Harkins
2014-10-15 13:38 ` James Harkins
2014-10-15 13:45   ` Nicolas Goaziou
     [not found]     ` <1491661ce88.27cd.0bb60a3c7e492ea180363c67eb170725@qq.com>
2014-10-16  1:01       ` James Harkins
2014-10-16 16:39         ` Nicolas Goaziou
2014-10-16 23:23           ` James Harkins
2014-10-17 20:22             ` Nicolas Goaziou
2014-10-18  2:21               ` James Harkins
2014-10-18  7:31                 ` Nicolas Goaziou
2014-10-20 12:46                   ` Bastien

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).