emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: "Tom Breton (Tehom)" <tehom@panix.com>
To: emacs-orgmode@gnu.org
Subject: Feature request and patch - blocked TODO to say BLOCKED
Date: Thu, 1 Jan 2009 17:53:57 -0500 (EST)	[thread overview]
Message-ID: <1131.66.30.178.137.1230850437.squirrel@mail.panix.com> (raw)
In-Reply-To: <20090101170227.C707734803@mail2.panix.com>


Motivating incident: I had a todo-type item that contained no tasks
itself, directly, but linked to other tasks.  I arranged it this way
in order that those other tasks could be placed neatly in a hierarchy
and not appear as "TODO" in two places.  I used the org-depend.el
BLOCKER code to manage this situation.  BTW, it works nicely.

But when a task is blocked, the heading is left with no "TODO" marking
at all.  That's not so bad for sibling tasks, because there's one
right above it that says "TODO" (or something).  But for distant-link
style tasks, IMO it gives a misleading impression that there is
nothing to do.

I request the following:

 * Object: One TODO workflow keyword set that relates specially to
   "BLOCKER".  It would be something like (sequence "BLOCKED" "|"
   "UNBLOCKED").
 * Behavior: When a C-c C-t change to a heading is blocked, instead of
   doing nothing, mark the heading with the first entry in the
   blockage workflow keyword set.
 * Behavior: Also do so when there is a blocked C-c C-t change to any
   heading whose TODO mark is in a state in the blockage workflow
   keyword set.
 * Behavior: Ordinarily don't offer the blockage workflow keyword set
   for C-c C-t and related commands.

I append a patch which does this.

The change mostly affects org.el, because allowing new TODO keywords
requires org.el to know about them, at least in computing some regular
expressions.  It was also a lot neater to let org-todo react to
blocked transitions than to try to make `org-depend-block-todo' do it,
which also avoided `org-todo' indirectly calling itself.

Summary of changes

Added 3 variables:
 * org-todo-use-blockage-keywords-p :: whether to use this
 * org-todo-blockage-keywords :: configurable keywords
 * org-blockage-keywords-1 :: internal

Encapsulated part of `org-set-regexps-and-options' as
`org-set-todo-constants'.  I had to because it needed to be called
twice, once for normal keywords and once with a flag for blockage
keywords.  I used encap-sexp to do it automatically (it's on my site,
http://panix.com/~tehom/my-code/), so no code changed, and I kept that
comment aligned with the regexp.

Made `org-set-regexps-and-options' also process
`org-todo-blockage-keywords'.

Changed the behavior of org-todo and org-depend-block-todo as described
above.

Tom Breton (Tehom)

*** org-depend.el	2008-12-18 18:26:05.000000000 -0500
--- new-org-depend.el	2009-01-01 17:13:13.000000000 -0500
***************
*** 196,204 ****
        (unless (eq type 'todo-state-change)
  	;; We are not handling this kind of change
  	(throw 'return t))
!       (unless (and (not from) (member to org-not-done-keywords))
! 	;; This is not a change from nothing to TODO, ignore it
! 	(throw 'return t))

        ;; OK, the plan is to switch from nothing to TODO
        ;; Lets see if we will allow it.  Find the BLOCKER property
--- 196,210 ----
        (unless (eq type 'todo-state-change)
  	;; We are not handling this kind of change
  	(throw 'return t))
!        ;;Act on only the right types of TODO-change:
!        (unless
! 	  (or
! 	     ;;A change from a member of the blockage set
! 	     (member from org-todo-blockage-keywords)
! 	     ;;A change from nothing to TODO
! 	     (and (not from) (member to org-not-done-keywords)))
! 	  ;; Otherwise ignore it
! 	  (throw 'return t))

        ;; OK, the plan is to switch from nothing to TODO
        ;; Lets see if we will allow it.  Find the BLOCKER property
*** old-org.el	2008-12-18 18:26:05.000000000 -0500
--- org.el	2009-01-01 17:25:32.000000000 -0500
***************
*** 1458,1464 ****
  		    (const :tag "Type     (cycling directly to DONE)" type))
  		   (repeat
  		    (string :tag "Keyword"))))))
-
  (defvar org-todo-keywords-1 nil
    "All TODO and DONE keywords active in a buffer.")
  (make-variable-buffer-local 'org-todo-keywords-1)
--- 1458,1463 ----
***************
*** 1483,1488 ****
--- 1482,1494 ----
  (make-variable-buffer-local 'org-todo-key-alist)
  (defvar org-todo-key-trigger nil)
  (make-variable-buffer-local 'org-todo-key-trigger)
+ (defvar org-todo-use-blockage-keywords-p t)
+ (defvar org-todo-blockage-keywords
+    '(sequence "BLOCKED" "|" "UNBLOCKED")
+    "Keywords of the blocking workflow keyword set." )
+ (defvar org-blockage-keywords-1 nil
+    "All blockage keywords active in a buffer" )
+ (make-variable-buffer-local 'org-blockage-keywords-1)

  (defcustom org-todo-interpretation 'sequence
    "Controls how TODO keywords are interpreted.
***************
*** 2997,3002 ****
--- 3003,3079 ----
  set this variable to if the option is found.  An optional forth element
PUSH
  means to push this value onto the list in the variable.")

+ (defun org-set-todo-constants (kwds block)
+    ""
+    (let
+       (inter kws kw)
+       (while
+ 	 (setq kws (pop kwds))
+ 	 (setq
+ 	    inter (pop kws)
+ 	    sep (member "|" kws)
+ 	    kws0 (delete "|"
+ 		    (copy-sequence kws))
+ 	    kwsa nil
+ 	    kws1
+ 	    (mapcar
+ 	       (lambda
+ 		  (x)
+ 		  (if
+ 		     ;;                 1              2
+ 		     (string-match "^\\(.*?\\)\\(?:(\\([^!@/]\\)?.*?)\\)?$" x)
+ 		     (progn
+ 			(setq kw
+ 			   (match-string 1 x)
+ 			   key
+ 			   (and
+ 			      (match-end 2)
+ 			      (match-string 2 x))
+ 			   log
+ 			   (org-extract-log-state-settings x))
+ 			(push
+ 			   (cons kw
+ 			      (and key
+ 				 (string-to-char key)))
+ 			   kwsa)
+ 			(and log
+ 			   (push log org-todo-log-states))
+ 			kw)
+ 		     (error "Invalid TODO keyword %s" x)))
+ 	       kws0)
+ 	    kwsa
+ 	    (if kwsa
+ 	       (append
+ 		  '((:startgroup))
+ 		  (nreverse kwsa)
+ 		  '((:endgroup))))
+ 	    hw (car kws1)
+ 	    dws (if sep
+ 		   (org-remove-keyword-keys
+ 		      (cdr sep))
+ 		   (last kws1))
+ 	    tail (list inter hw
+ 		    (car dws)
+ 		    (org-last dws)))
+ 	 (add-to-list 'org-todo-heads hw 'append)
+ 	 (push kws1 org-todo-sets)
+ 	 (setq org-done-keywords
+ 	    (append org-done-keywords dws nil))
+ 	 (setq org-todo-key-alist
+ 	    (append org-todo-key-alist kwsa))
+ 	 (mapc
+ 	    (lambda
+ 	       (x)
+ 	       (push
+ 		  (cons x tail)
+ 		  org-todo-kwd-alist))
+ 	    kws1)
+ 	 (if block
+ 	    (setq org-blockage-keywords-1
+ 	       (append org-blockage-keywords-1 kws1 nil)))
+ 	 (setq org-todo-keywords-1
+ 	    (append org-todo-keywords-1 kws1 nil)))))
+
  (defun org-set-regexps-and-options ()
    "Precompute regular expressions for current buffer."
    (when (org-mode-p)
***************
*** 3116,3156 ****
  	    (setq kwds (list (cons org-todo-interpretation
  				   (default-value 'org-todo-keywords)))))
  	(setq kwds (reverse kwds)))
!       (setq kwds (nreverse kwds))
!       (let (inter kws kw)
! 	(while (setq kws (pop kwds))
! 	  (setq inter (pop kws) sep (member "|" kws)
! 		kws0 (delete "|" (copy-sequence kws))
! 		kwsa nil
! 		kws1 (mapcar
! 		      (lambda (x)
! 			;;                     1              2
! 			(if (string-match "^\\(.*?\\)\\(?:(\\([^!@/]\\)?.*?)\\)?$" x)
! 			    (progn
! 			      (setq kw (match-string 1 x)
! 				    key (and (match-end 2) (match-string 2 x))
! 				    log (org-extract-log-state-settings x))
! 			      (push (cons kw (and key (string-to-char key))) kwsa)
! 			      (and log (push log org-todo-log-states))
! 			      kw)
! 			  (error "Invalid TODO keyword %s" x)))
! 		      kws0)
! 		kwsa (if kwsa (append '((:startgroup))
! 				      (nreverse kwsa)
! 				      '((:endgroup))))
! 		hw (car kws1)
! 		dws (if sep (org-remove-keyword-keys (cdr sep)) (last kws1))
! 		tail (list inter hw (car dws) (org-last dws)))
! 	  (add-to-list 'org-todo-heads hw 'append)
! 	  (push kws1 org-todo-sets)
! 	  (setq org-done-keywords (append org-done-keywords dws nil))
! 	  (setq org-todo-key-alist (append org-todo-key-alist kwsa))
! 	  (mapc (lambda (x) (push (cons x tail) org-todo-kwd-alist)) kws1)
! 	  (setq org-todo-keywords-1 (append org-todo-keywords-1 kws1 nil)))
! 	(setq org-todo-sets (nreverse org-todo-sets)
! 	      org-todo-kwd-alist (nreverse org-todo-kwd-alist)
! 	      org-todo-key-trigger (delq nil (mapcar 'cdr org-todo-key-alist))
! 	      org-todo-key-alist (org-assign-fast-keys org-todo-key-alist)))
        ;; Process the constants
        (when const
  	(let (e cst)
--- 3193,3209 ----
  	    (setq kwds (list (cons org-todo-interpretation
  				   (default-value 'org-todo-keywords)))))
  	(setq kwds (reverse kwds)))
!       ;;(setq kwds (append (nreverse kwds) (list
org-todo-blockage-keywords)))
!       (org-set-todo-constants (nreverse kwds) nil)
!        (when org-todo-use-blockage-keywords-p
! 	  (org-set-todo-constants (list org-todo-blockage-keywords) t))
!       (setq
! 	 org-todo-sets (nreverse org-todo-sets)
! 	 org-todo-kwd-alist (nreverse org-todo-kwd-alist)
! 	 org-todo-key-trigger (delq nil
! 				 (mapcar 'cdr org-todo-key-alist))
! 	 org-todo-key-alist (org-assign-fast-keys org-todo-key-alist))
!
        ;; Process the constants
        (when const
  	(let (e cst)
***************
*** 8222,8232 ****
  		    (save-match-data
  		      (run-hook-with-args-until-failure
  		       'org-blocker-hook change-plist)))
! 	    (if (interactive-p)
! 		(error "TODO state change from %s to %s blocked" this state)
! 	      ;; fail silently
! 	      (message "TODO state change from %s to %s blocked" this state)
! 	      (throw 'exit nil))))
  	(store-match-data match-data)
  	(replace-match next t t)
  	(unless (pos-visible-in-window-p hl-pos)
--- 8275,8294 ----
  		    (save-match-data
  		      (run-hook-with-args-until-failure
  		       'org-blocker-hook change-plist)))
! 	     (if
! 		org-todo-use-blockage-keywords-p
! 		(let
! 		   ((blocked-state (car org-blockage-keywords-1)))
! 		   (setq arg 'none)
! 		   (setq next (concat " " blocked-state " "))
! 		   (unless
! 		      (string= state blocked-state)
! 		      (message "TODO state change from %s to %s blocked" this state)))
! 		(if (interactive-p)
! 		   (error "TODO state change from %s to %s blocked" this state)
! 		   ;; fail silently
! 		   (message "TODO state change from %s to %s blocked" this state)
! 		   (throw 'exit nil)))))
  	(store-match-data match-data)
  	(replace-match next t t)
  	(unless (pos-visible-in-window-p hl-pos)

       reply	other threads:[~2009-01-01 22:53 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20090101170227.C707734803@mail2.panix.com>
2009-01-01 22:53 ` Tom Breton (Tehom) [this message]
2009-01-09  8:16   ` Feature request and patch - blocked TODO to say BLOCKED Carsten Dominik
2009-01-15  2:34     ` Tom Breton (Tehom)
2009-01-17  8:01       ` Carsten Dominik
2009-01-19  3:33     ` Advice sought on managing decision alternatives Tom Breton (Tehom)
2009-01-22 11:15       ` Carsten Dominik
2009-01-31  4:21         ` Tom Breton (Tehom)
2009-01-31  5:41           ` Carsten Dominik
2009-01-31 18:36             ` Tom Breton (Tehom)
2009-02-01 15:54               ` James TD Smith
2009-02-06 13:08           ` Carsten Dominik
2009-02-06 16:16             ` William Henney
2009-02-06 20:07             ` Tom Breton (Tehom)
2009-02-07  0:18               ` Carsten Dominik
2009-02-07 20:46                 ` Tom Breton (Tehom)
2009-02-08 13:06                   ` Carsten Dominik
2009-02-08 20:25                     ` Tom Breton (Tehom)
2009-02-09  6:42                       ` Carsten Dominik
2009-02-10  3:14                         ` Docs submitted (Was Re: Advice sought on managing decision alternatives.) Tom Breton (Tehom)
2009-02-10  7:55                           ` Carsten Dominik
2009-02-24  0:51                             ` org-choose bugfix Tom Breton (Tehom)
2009-02-24  3:05                               ` Manish
2009-04-07  0:13                                 ` Tom Breton (Tehom)
2009-04-08 13:13                                   ` Carsten Dominik
2009-02-24  5:51                               ` Carsten Dominik
2009-02-10  8:46                           ` Docs submitted (Was Re: Advice sought on managing decision alternatives.) Manish
2009-02-10  9:12                             ` Carsten Dominik
2009-02-10 10:26                               ` Manish
2009-02-10 22:48                                 ` Tom Breton (Tehom)
2009-02-12 12:50                                   ` Manish
2009-02-12 20:13                                     ` Tom Breton (Tehom)
2009-02-13  4:23                                       ` Manish
2009-02-12 20:55                                     ` Patch " Tom Breton (Tehom)
2009-02-13  4:38                                       ` Manish
2009-02-11  1:08                                 ` Tom Breton (Tehom)
2009-02-11 10:34                                   ` Carsten Dominik
2009-02-11 21:41                                     ` Tom Breton (Tehom)
2009-02-11 23:38                                       ` Nick Dokos
2009-02-12  4:17                                         ` Tom Breton (Tehom)
2009-02-11 23:44                                       ` Carsten Dominik
2009-02-12  4:27                                         ` Tom Breton (Tehom)
2009-02-12 15:49                                           ` Nick Dokos
2009-02-12 20:32                                             ` Tom Breton (Tehom)
2009-02-12 21:25                                               ` Nick Dokos
2009-02-11 12:29                                   ` Carsten Dominik
2009-02-11 14:58                                     ` Docs submitted Bernt Hansen
2009-02-11 17:33                                       ` Samuel Wales
2009-02-11 15:38                                     ` Docs submitted (Was Re: Advice sought on managing decision alternatives.) Daniel Clemente
2009-02-11 15:41                                       ` Carsten Dominik
2009-02-11 20:02                                     ` Tom Breton (Tehom)
2009-02-11 23:45                                       ` Carsten Dominik
2009-02-11  1:45                                 ` Slight fix to update-org.sh Tom Breton (Tehom)
2009-02-10 23:19                               ` Docs submitted (Was Re: Advice sought on managing decision alternatives.) Tom Breton (Tehom)
2009-02-11 10:34                                 ` Carsten Dominik
2009-02-10 22:45                             ` Tom Breton (Tehom)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1131.66.30.178.137.1230850437.squirrel@mail.panix.com \
    --to=tehom@panix.com \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).