* [PATCH] New org-depend trigger for finding next highest priority/effort item @ 2011-07-24 18:58 Max Mikhanosha 2011-07-26 11:48 ` Bastien 0 siblings, 1 reply; 10+ messages in thread From: Max Mikhanosha @ 2011-07-24 18:58 UTC (permalink / raw) To: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 581 bytes --] org-depend TRIGGER chain-siblings(NEXT) property is hardly usable for me, because it requires too much effort to keep items nicely sorted. For example if next headline is already in DONE state, chain-siblings would still change it. I prefer to sort my items by setting their priorities and/or effort estimate, leaving DONE items in place for some time. Attached patch implements new TRIGGER chain-find-next(NEXT[,options]) trigger, which allows to flexibly select which of the siblings will be changed to NEXT. Example: chain-find-next(NEXT,from-current,priority-up,todo-only) [-- Attachment #2: 0011-Add-chain-find-next-trigger-option.patch --] [-- Type: application/octet-stream, Size: 7711 bytes --] From 10ac42d25793eedc595641555186321219818cec Mon Sep 17 00:00:00 2001 From: Max Mikhanosha <max@openchat.com> Date: Sun, 24 Jul 2011 14:44:44 -0400 Subject: [PATCH 11/11] Add chain-find-next trigger option. --- contrib/lisp/org-depend.el | 142 +++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 140 insertions(+), 2 deletions(-) diff --git a/contrib/lisp/org-depend.el b/contrib/lisp/org-depend.el index 089a6a0..aa8e728 100644 --- a/contrib/lisp/org-depend.el +++ b/contrib/lisp/org-depend.el @@ -55,7 +55,43 @@ ;; - The sibling also gets the same TRIGGER property ;; "chain-siblings-scheduled", so the chain can continue. ;; -;; 3) If the TRIGGER property contains any other words like +;; 3) If the TRIGGER property contains the string +;; "chain-find-next(KEYWORD[,OPTIONS])", then switching that entry +;; to DONE do the following: +;; - All siblings are of the entry are collected into a temporary +;; list and then filtered and sorted according to OPTIONS +;; - The first sibling on the list is changed into KEYWORD state +;; - The sibling also gets the same TRIGGER property +;; "chain-siblings-scheduled", so the chain can continue. +;; OPTIONS should be a comma separated string without spaces, and +;; can contain following options: +;; +;; - from-top the candidate list is all of the siblings in +;; the current subtree +;; +;; - from-bottom candidate list are all siblings from bottom up +;; +;; - from-current candidate list are all siblings from current item +;; until end of subtree, then wrapped around from +;; first sibling +;; +;; - no-wrap candidate list are siblings from current one down +;; +;; - include-done include siblings with TODO in `org-done-keywords', +;; they are excluded by default +;; +;; - todo-only Only consider siblings that have TODO only, by default +;; siblings without TODO keyword are considered too +;; +;; - priority-up sort by highest priority +;; - priority-down sort by lowest priority +;; - effort-up sort by highest effort +;; - effort-down sort by lowest effort +;; +;; Default OPTIONS are from-top +;; +;; +;; 4) If the TRIGGER property contains any other words like ;; XYZ(KEYWORD), these are treated as entry id's with keywords. That ;; means Org-mode will search for an entry with the ID property XYZ ;; and switch that entry to KEYWORD as well. @@ -121,6 +157,7 @@ ;; (require 'org) +(require 'cl) (defcustom org-depend-tag-blocked t "Whether to indicate blocked TODO items by a special tag." @@ -143,6 +180,8 @@ copying the sibling spec TRIGGER-VAL to the next sibling." (org-entry-add-to-multivalued-property nil "TRIGGER" ,trigger-val)))) +(defvar org-depend-doing-chain-find-next nil) + (defun org-depend-trigger-todo (change-plist) "Trigger new TODO entries after the current is switched to DONE. This does two different kinds of triggers: @@ -184,12 +223,111 @@ This does two different kinds of triggers: ;; Go through all the triggers (while (setq tr (pop triggers)) (cond + ((and (not org-depend-doing-chain-find-next) + (string-match "\\`chain-find-next(\\b\\(.+?\\)\\b\\(.*\\))\\'" tr)) + ;; smarter sibling selection + ;; keywords + ;; + ;; include-done => include siblings in DONE todo states + ;; todo-only => only todo items, otherwise will consider items without any todo keyword too + ;; from-top => candidates siblings are in sequential order + ;; from-bottom => candidate siblings are in reverse order + ;; from-current => candidate siblings are from current one down + ;; no-wrap => used together with from current, stop if reached + ;; the end, otherwise it wraps + ;; priority-up => use highest priority + ;; effort-down => use shortest effort + (let* ((org-depend-doing-chain-find-next t) + (kwd (match-string 1 tr)) + (options (match-string 2 tr)) + (include-done (string-match "include-done" options)) + (todo-only (string-match "todo-only" options)) + (from-top (string-match "from-top" options)) + (from-bottom (string-match "from-bottom" options)) + (from-current (string-match "from-current" options)) + (no-wrap (string-match "no-wrap" options)) + (priority-up (string-match "priority-up" options)) + (priority-down (string-match "priority-down" options)) + (effort-up (string-match "effort-up" options)) + (effort-down (string-match "effort-down" options))) + (save-excursion + (org-back-to-heading t) + (let ((this-item (point))) + ;; go up to the parent headline, then advance to next child + (org-up-heading-safe) + (let ((end (save-excursion (org-end-of-subtree t) + (point))) + (done nil) + (items '())) + (outline-next-heading) + (while (not done) + (if (not (looking-at org-complex-heading-regexp)) + (setq done t) + (let ((todo-kwd (match-string 2)) + (tags (match-string 5)) + (priority (org-get-priority (or (match-string 3) ""))) + (effort (when (or effort-up effort-down) + (let ((effort (org-get-effort))) + (when effort + (org-duration-string-to-minutes effort)))))) + (push (list (point) todo-kwd priority tags effort) + items)) + (unless (org-goto-sibling) + (setq done t)))) + ;; massage the list according to options + (setq items + (cond (from-top (nreverse items)) + (from-bottom items) + ((or from-current no-wrap) + (let* ((items (nreverse items)) + (pos (position this-item items :key #'first)) + (items-before (subseq items 0 pos)) + (items-after (subseq items pos))) + (if no-wrap items-after + (append items-after items-before)))) + (t (nreverse items)))) + (setq items (remove-if + (lambda (item) + (or (equal (first item) this-item) + (and (not include-done) + (member (second item) org-done-keywords)) + (and todo-only (null (second item))))) + items)) + (setq items + (sort + items + (lambda (item1 item2) + (let* ((p1 (third item1)) + (p2 (third item2)) + (e1 (fifth item1)) + (e2 (fifth item2)) + (p1-lt (< p1 p2)) + (p1-gt (> p1 p2)) + (e1-lt (and e1 (or (not e2) (< e1 e2)))) + (e2-gt (and e2 (or (not e1) (> e1 e2))))) + (cond (priority-up + (or p1-gt + (and (equal p1 p2) + (or (and effort-up e1-gt) + (and effort-down e1-lt))))) + (priority-down + (or p1-lt + (and (equal p1 p2) + (or (and effort-up e1-gt) + (and effort-down e1-lt))))) + (effort-up + (or e1-gt (and (equal e1 e2) p1-gt))) + (effort-down + (or e1-lt (and (equal e1 e2) p1-gt)))))))) + (when items + (goto-char (first (first items))) + (org-entry-add-to-multivalued-property nil "TRIGGER" tr) + (org-todo kwd))))))) ((string-match "\\`chain-siblings(\\(.*?\\))\\'" tr) ;; This is a TODO chain of siblings (setq kwd (match-string 1 tr)) (org-depend-act-on-sibling (format "chain-siblings(%s)" kwd) (org-todo kwd))) - ((string-match "\\`\\(\\S-+\\)(\\(.*?\\))\\'" tr) ;; This seems to be ENTRY_ID(KEYWORD) (setq id (match-string 1 tr) -- 1.7.3.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] New org-depend trigger for finding next highest priority/effort item 2011-07-24 18:58 [PATCH] New org-depend trigger for finding next highest priority/effort item Max Mikhanosha @ 2011-07-26 11:48 ` Bastien 2011-07-26 12:52 ` Sebastien Vauban ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Bastien @ 2011-07-26 11:48 UTC (permalink / raw) To: Max Mikhanosha; +Cc: emacs-orgmode Hi Max, Max Mikhanosha <max@openchat.com> writes: > org-depend TRIGGER chain-siblings(NEXT) property is hardly usable for > me, because it requires too much effort to keep items nicely sorted. > > For example if next headline is already in DONE state, chain-siblings > would still change it. I prefer to sort my items by setting their > priorities and/or effort estimate, leaving DONE items in place for > some time. > > Attached patch implements new TRIGGER chain-find-next(NEXT[,options]) > trigger, which allows to flexibly select which of the siblings will be > changed to NEXT. Thanks for this! > Example: chain-find-next(NEXT,from-current,priority-up,todo-only) > > >From 10ac42d25793eedc595641555186321219818cec Mon Sep 17 00:00:00 2001 > From: Max Mikhanosha <max@openchat.com> > Date: Sun, 24 Jul 2011 14:44:44 -0400 > Subject: [PATCH 11/11] Add chain-find-next trigger option. > > --- > contrib/lisp/org-depend.el | 142 +++++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 140 insertions(+), 2 deletions(-) > > diff --git a/contrib/lisp/org-depend.el b/contrib/lisp/org-depend.el > index 089a6a0..aa8e728 100644 > --- a/contrib/lisp/org-depend.el > +++ b/contrib/lisp/org-depend.el > @@ -55,7 +55,43 @@ > ;; - The sibling also gets the same TRIGGER property > ;; "chain-siblings-scheduled", so the chain can continue. > ;; > -;; 3) If the TRIGGER property contains any other words like > +;; 3) If the TRIGGER property contains the string > +;; "chain-find-next(KEYWORD[,OPTIONS])", then switching that entry > +;; to DONE do the following: > +;; - All siblings are of the entry are collected into a temporary > +;; list and then filtered and sorted according to OPTIONS > +;; - The first sibling on the list is changed into KEYWORD state > +;; - The sibling also gets the same TRIGGER property > +;; "chain-siblings-scheduled", so the chain can continue. ^^^^^^^^^^^^^^^^^^^^^^^^ This should rather be "chain-find-next" here, right? > +;; OPTIONS should be a comma separated string without spaces, and > +;; can contain following options: > +;; > +;; - from-top the candidate list is all of the siblings in > +;; the current subtree > +;; > +;; - from-bottom candidate list are all siblings from bottom up > +;; > +;; - from-current candidate list are all siblings from current item > +;; until end of subtree, then wrapped around from > +;; first sibling > +;; > +;; - no-wrap candidate list are siblings from current one down I'm not sure to understand the difference between "from-top" and "from-current", and between "from-top" and "no-wrap". Can you give an example? > +;; > +;; - include-done include siblings with TODO in `org-done-keywords', > +;; they are excluded by default The phrasing is a bit confusing to me -- perhaps removing "they are excluded by default" is enough. > +;; - todo-only Only consider siblings that have TODO only, by default > +;; siblings without TODO keyword are considered too I suggest this: "Only consider siblings that have a TODO keyword." I suppose "todo-only" and "include-done" are compatible, right? What about using exclusive options like "todo-only" and "todo-and-done-only"? So that you would need to use only one. > +;; - priority-up sort by highest priority > +;; - priority-down sort by lowest priority > +;; - effort-up sort by highest effort > +;; - effort-down sort by lowest effort > +;; > +;; Default OPTIONS are from-top > +;; > +;; > +;; 4) If the TRIGGER property contains any other words like > ;; XYZ(KEYWORD), these are treated as entry id's with keywords. That > ;; means Org-mode will search for an entry with the ID property XYZ > ;; and switch that entry to KEYWORD as well. > @@ -121,6 +157,7 @@ > ;; > > (require 'org) > +(require 'cl) This (eval-when-compile (require 'cl)) -- Emacs has a policy of preventing (require 'cl) only... Thanks for further feedback on this! If you can provide a small Org file where I can test the new functionalities that will help a lot. Best, -- Bastien ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New org-depend trigger for finding next highest priority/effort item 2011-07-26 11:48 ` Bastien @ 2011-07-26 12:52 ` Sebastien Vauban 2011-07-26 14:59 ` Bastien 2011-07-26 21:56 ` Max Mikhanosha 2011-07-26 23:34 ` Max Mikhanosha 2 siblings, 1 reply; 10+ messages in thread From: Sebastien Vauban @ 2011-07-26 12:52 UTC (permalink / raw) To: emacs-orgmode-mXXj517/zsQ Hi Bastien, Bastien wrote: >> +(require 'cl) > > This (eval-when-compile (require 'cl)) -- Emacs has a policy of > preventing (require 'cl) only... Shouldn't we do that (require cl only) in our custom .emacs files neither? I do have such for accessing functions like `push'... Best regards, Seb -- Sebastien Vauban ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New org-depend trigger for finding next highest priority/effort item 2011-07-26 12:52 ` Sebastien Vauban @ 2011-07-26 14:59 ` Bastien 0 siblings, 0 replies; 10+ messages in thread From: Bastien @ 2011-07-26 14:59 UTC (permalink / raw) To: Sebastien Vauban; +Cc: emacs-orgmode "Sebastien Vauban" <wxhgmqzgwmuf@spammotel.com> writes: > Shouldn't we do that (require cl only) in our custom .emacs files > neither? ~/.emacs.el is precisely the place where you do what you want :) -- Bastien ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New org-depend trigger for finding next highest priority/effort item 2011-07-26 11:48 ` Bastien 2011-07-26 12:52 ` Sebastien Vauban @ 2011-07-26 21:56 ` Max Mikhanosha 2011-07-27 11:33 ` Bastien 2011-07-26 23:34 ` Max Mikhanosha 2 siblings, 1 reply; 10+ messages in thread From: Max Mikhanosha @ 2011-07-26 21:56 UTC (permalink / raw) To: Bastien; +Cc: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 4273 bytes --] At Tue, 26 Jul 2011 13:48:30 +0200, Bastien wrote: > > > +;; list and then filtered and sorted according to OPTIONS > > +;; - The first sibling on the list is changed into KEYWORD state > > +;; - The sibling also gets the same TRIGGER property > > +;; "chain-siblings-scheduled", so the chain can continue. > > This should rather be "chain-find-next" here, right? Yes thats a typo, I was trying to select a more appropriate name for it. > > +;; OPTIONS should be a comma separated string without spaces, and > > +;; can contain following options: > > +;; > > +;; - from-top the candidate list is all of the siblings in > > +;; the current subtree > > +;; > > +;; - from-bottom candidate list are all siblings from bottom up > > +;; > > +;; - from-current candidate list are all siblings from current item > > +;; until end of subtree, then wrapped around from > > +;; first sibling > > +;; > > +;; - no-wrap candidate list are siblings from current one down > > I'm not sure to understand the difference between "from-top" and > "from-current", and between "from-top" and "no-wrap". > > Can you give an example? * Parent ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (the one with TRIGGER property) ** TODO Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 Below are example list of candidates depending on option from-top => 1,2,3,4,6,7,8 from-bottom => 8,7,6,4,3,2,1 from-current => 6,7,8,1,2,3,4 from-current,no-wrap => 6,7,8 Adding todo-only will eliminate item 7 from all of above, adding include-done will include item 9. After inital candidate list is established as above, its sorted by priority or effort, then 1st item is made NEXT. > > +;; > > +;; - include-done include siblings with TODO in `org-done-keywords', > > +;; they are excluded by default > > The phrasing is a bit confusing to me -- perhaps removing "they are > excluded by default" is enough. Agree, maybe whole option can be eliminated, I had an opposite option initially (skip-done), to have default compatible with original trigger, but decided that skipping done may be a better default. > > +;; - todo-only Only consider siblings that have TODO only, by default > > +;; siblings without TODO keyword are considered too > > I suggest this: > > "Only consider siblings that have a TODO keyword." > > I suppose "todo-only" and "include-done" are compatible, right? todo-only excludes items without any todo keyword, ie plain headlines. See example above on if item 7 is included or not. include-done forces items with a DONE/CANCELLEd keyword to be considered > > What about using exclusive options like "todo-only" and > "todo-and-done-only"? So that you would need to use only one. I'm fine with that, will change. > > > > (require 'org) > > +(require 'cl) > > this (eval-when-compile (require 'cl)) -- emacs has a policy of > preventing (require 'cl) only... I grepped *.el and saw other file using it without eval-when-compile (it was htmlize.el i think), so I thought it was ok in contrib. My worry was that using functions as opposite to macros needs it loaded, since I use (remove-if) and (position) But I just tested it on clean file and emacs -Q, and (eval-when-compile (require 'cl)) and then using 'cl-seq functions like remove-if seems to works fine. I'll submit updated patch later today taken above comments inte consideration. Attached is an org file where you can test various options > Thanks for further feedback on this! If you can provide a small > Org file where I can test the new functionalities that will help > a lot. Attached is a test file you can use for all the situation that you asked clarification for. After testing this file I'm thinking maybe from-current should be a default instead of from-top. Basically I'm open to suggestion as to the most sensible default options. I myself use a hook that auto-inserts TRIGGER line i want when entry becomes next, maybe such hook should be included into org-depend also? At least as example? [-- Attachment #2: org-depend-chain-find-next-test.org --] [-- Type: application/octet-stream, Size: 2533 bytes --] * Default ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT) :END: ** TODO Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-top (same as default) ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-top) :END: ** TODO Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-bottom ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-bottom) :END: ** TODO Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-current,priority-up ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO [#A] Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current,priority-up) :END: ** TODO Item 6 ** Item 7 ** TODO [#B] Item 8 ** DONE Item 9 * from-current,no-wrap,priority-up ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO [#A] Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current,no-wrap,priority-up) :END: ** TODO Item 6 ** Item 7 ** TODO [#B] Item 8 ** DONE Item 9 * from-current, without todo-only ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current) :END: ** Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-current, with todo-only ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current,todo-only) :END: ** Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-current without include-done ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current) :END: ** DONE Item 6 CLOSED: [2011-07-26 Tue 17:49] ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-current with include-done ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current,include-done) :END: ** DONE Item 6 CLOSED: [2011-07-26 Tue 17:49] ** Item 7 ** TODO Item 8 ** DONE Item 9 * end [-- Attachment #3: Type: text/plain, Size: 3 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New org-depend trigger for finding next highest priority/effort item 2011-07-26 21:56 ` Max Mikhanosha @ 2011-07-27 11:33 ` Bastien 2011-07-27 19:45 ` Max Mikhanosha 0 siblings, 1 reply; 10+ messages in thread From: Bastien @ 2011-07-27 11:33 UTC (permalink / raw) To: Max Mikhanosha; +Cc: emacs-orgmode Hi Max, Max Mikhanosha <max@openchat.com> writes: >> Can you give an example? > > * Parent > ** TODO Item 1 > ** TODO Item 2 > ** TODO Item 3 > ** TODO Item 4 > ** NEXT Item 5 Current (the one with TRIGGER property) > ** TODO Item 6 > ** Item 7 > ** TODO Item 8 > ** DONE Item 9 > > Below are example list of candidates depending on option > > from-top => 1,2,3,4,6,7,8 > from-bottom => 8,7,6,4,3,2,1 > from-current => 6,7,8,1,2,3,4 > from-current,no-wrap => 6,7,8 > > Adding todo-only will eliminate item 7 from all of above, adding > include-done will include item 9. > > After inital candidate list is established as above, its sorted by priority > or effort, then 1st item is made NEXT. Cristal-clear, thanks! > I grepped *.el and saw other file using it without eval-when-compile > (it was htmlize.el i think), so I thought it was ok in contrib. To be clear: it *is* okay in contrib/ as files in contrib/ will not go to Emacs core. But the more we can avoid this the better. > Attached is a test file you can use for all the situation that you > asked clarification for. After testing this file I'm thinking maybe > from-current should be a default instead of from-top. Yes, I also think from-current should be the default. Also, it would be really nice to update this tutorial on Worg and to show how to use the new feature you introduced: http://orgmode.org/worg/org-contrib/org-depend.html Thanks! -- Bastien ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New org-depend trigger for finding next highest priority/effort item 2011-07-27 11:33 ` Bastien @ 2011-07-27 19:45 ` Max Mikhanosha 2011-07-28 7:11 ` Bastien 0 siblings, 1 reply; 10+ messages in thread From: Max Mikhanosha @ 2011-07-27 19:45 UTC (permalink / raw) To: Bastien; +Cc: emacs-orgmode At Wed, 27 Jul 2011 13:33:16 +0200, Bastien wrote: > > Also, it would be really nice to update this tutorial on Worg and to > show how to use the new feature you introduced: > > http://orgmode.org/worg/org-contrib/org-depend.html > Done, will push once I have permissions ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New org-depend trigger for finding next highest priority/effort item 2011-07-27 19:45 ` Max Mikhanosha @ 2011-07-28 7:11 ` Bastien 0 siblings, 0 replies; 10+ messages in thread From: Bastien @ 2011-07-28 7:11 UTC (permalink / raw) To: Max Mikhanosha; +Cc: emacs-orgmode Hi Max, Max Mikhanosha <max@openchat.com> writes: > At Wed, 27 Jul 2011 13:33:16 +0200, > Bastien wrote: >> >> Also, it would be really nice to update this tutorial on Worg and to >> show how to use the new feature you introduced: >> >> http://orgmode.org/worg/org-contrib/org-depend.html > > Done, will push once I have permissions Great -- thanks. The person to contact to get write access to Worg's repo is Matt Lundin, but if you give me your username on repo.or.cz I can add you now. Best, -- Bastien ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New org-depend trigger for finding next highest priority/effort item 2011-07-26 11:48 ` Bastien 2011-07-26 12:52 ` Sebastien Vauban 2011-07-26 21:56 ` Max Mikhanosha @ 2011-07-26 23:34 ` Max Mikhanosha 2011-07-27 11:33 ` Bastien 2 siblings, 1 reply; 10+ messages in thread From: Max Mikhanosha @ 2011-07-26 23:34 UTC (permalink / raw) To: Bastien; +Cc: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 8122 bytes --] Amended patch attached, changes: - use (eval-when-compile) with require 'cl - changed include-done to todo-and-done-only - Added defcustom org-depend-find-next-options for default options which are now: from-current,todo-only,priority-up - cleaned up documentation Also attached is updated test file, added #+TODO line since NEXT is not in default list of keywords. Content-Disposition: attachment; filename="0011-Add-chain-find-next-trigger-option.patch"][8bit]] From 6140261b2fe0e15ac36d8222c38790680cd3f9d4 Mon Sep 17 00:00:00 2001 From: Max Mikhanosha <max@openchat.com> Date: Sun, 24 Jul 2011 14:44:44 -0400 Subject: [PATCH 11/11] Add chain-find-next trigger option. --- contrib/lisp/org-depend.el | 145 +++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 143 insertions(+), 2 deletions(-) diff --git a/contrib/lisp/org-depend.el b/contrib/lisp/org-depend.el index 089a6a0..77a7c68 100644 --- a/contrib/lisp/org-depend.el +++ b/contrib/lisp/org-depend.el @@ -55,7 +55,43 @@ ;; - The sibling also gets the same TRIGGER property ;; "chain-siblings-scheduled", so the chain can continue. ;; -;; 3) If the TRIGGER property contains any other words like +;; 3) If the TRIGGER property contains the string +;; "chain-find-next(KEYWORD[,OPTIONS])", then switching that entry +;; to DONE do the following: +;; - All siblings are of the entry are collected into a temporary +;; list and then filtered and sorted according to OPTIONS +;; - The first sibling on the list is changed into KEYWORD state +;; - The sibling also gets the same TRIGGER property +;; "chain-find-next", so the chain can continue. +;; +;; OPTIONS should be a comma separated string without spaces, and +;; can contain following options: +;; +;; - from-top the candidate list is all of the siblings in +;; the current subtree +;; +;; - from-bottom candidate list are all siblings from bottom up +;; +;; - from-current candidate list are all siblings from current item +;; until end of subtree, then wrapped around from +;; first sibling +;; +;; - no-wrap candidate list are siblings from current one down +;; +;; - todo-only Only consider siblings that have a todo keyword +;; - +;; - todo-and-done-only +;; Same as above but also include done items. +;; +;; - priority-up sort by highest priority +;; - priority-down sort by lowest priority +;; - effort-up sort by highest effort +;; - effort-down sort by lowest effort +;; +;; Default OPTIONS are from-top +;; +;; +;; 4) If the TRIGGER property contains any other words like ;; XYZ(KEYWORD), these are treated as entry id's with keywords. That ;; means Org-mode will search for an entry with the ID property XYZ ;; and switch that entry to KEYWORD as well. @@ -121,12 +157,20 @@ ;; (require 'org) +(eval-when-compile + (require 'cl)) (defcustom org-depend-tag-blocked t "Whether to indicate blocked TODO items by a special tag." :group 'org :type 'boolean) +(defcustom org-depend-find-next-options + "from-current,todo-only,priority-up" + "Default options for chain-find-next trigger" + :group 'org + :type 'string) + (defmacro org-depend-act-on-sibling (trigger-val &rest rest) "Perform a set of actions on the next sibling, if it exists, copying the sibling spec TRIGGER-VAL to the next sibling." @@ -143,6 +187,8 @@ copying the sibling spec TRIGGER-VAL to the next sibling." (org-entry-add-to-multivalued-property nil "TRIGGER" ,trigger-val)))) +(defvar org-depend-doing-chain-find-next nil) + (defun org-depend-trigger-todo (change-plist) "Trigger new TODO entries after the current is switched to DONE. This does two different kinds of triggers: @@ -184,12 +230,107 @@ This does two different kinds of triggers: ;; Go through all the triggers (while (setq tr (pop triggers)) (cond + ((and (not org-depend-doing-chain-find-next) + (string-match "\\`chain-find-next(\\b\\(.+?\\)\\b\\(.*\\))\\'" tr)) + ;; smarter sibling selection + (let* ((org-depend-doing-chain-find-next t) + (kwd (match-string 1 tr)) + (options (match-string 2 tr)) + (options (if (or (null options) + (equal options "")) + org-depend-find-next-options + options)) + (todo-only (string-match "todo-only" options)) + (todo-and-done-only (string-match "todo-and-done-only" + options)) + (from-top (string-match "from-top" options)) + (from-bottom (string-match "from-bottom" options)) + (from-current (string-match "from-current" options)) + (no-wrap (string-match "no-wrap" options)) + (priority-up (string-match "priority-up" options)) + (priority-down (string-match "priority-down" options)) + (effort-up (string-match "effort-up" options)) + (effort-down (string-match "effort-down" options))) + (save-excursion + (org-back-to-heading t) + (let ((this-item (point))) + ;; go up to the parent headline, then advance to next child + (org-up-heading-safe) + (let ((end (save-excursion (org-end-of-subtree t) + (point))) + (done nil) + (items '())) + (outline-next-heading) + (while (not done) + (if (not (looking-at org-complex-heading-regexp)) + (setq done t) + (let ((todo-kwd (match-string 2)) + (tags (match-string 5)) + (priority (org-get-priority (or (match-string 3) ""))) + (effort (when (or effort-up effort-down) + (let ((effort (org-get-effort))) + (when effort + (org-duration-string-to-minutes effort)))))) + (push (list (point) todo-kwd priority tags effort) + items)) + (unless (org-goto-sibling) + (setq done t)))) + ;; massage the list according to options + (setq items + (cond (from-top (nreverse items)) + (from-bottom items) + ((or from-current no-wrap) + (let* ((items (nreverse items)) + (pos (position this-item items :key #'first)) + (items-before (subseq items 0 pos)) + (items-after (subseq items pos))) + (if no-wrap items-after + (append items-after items-before)))) + (t (nreverse items)))) + (setq items (remove-if + (lambda (item) + (or (equal (first item) this-item) + (and (not todo-and-done-only) + (member (second item) org-done-keywords)) + (and (or todo-only + todo-and-done-only) + (null (second item))))) + items)) + (setq items + (sort + items + (lambda (item1 item2) + (let* ((p1 (third item1)) + (p2 (third item2)) + (e1 (fifth item1)) + (e2 (fifth item2)) + (p1-lt (< p1 p2)) + (p1-gt (> p1 p2)) + (e1-lt (and e1 (or (not e2) (< e1 e2)))) + (e2-gt (and e2 (or (not e1) (> e1 e2))))) + (cond (priority-up + (or p1-gt + (and (equal p1 p2) + (or (and effort-up e1-gt) + (and effort-down e1-lt))))) + (priority-down + (or p1-lt + (and (equal p1 p2) + (or (and effort-up e1-gt) + (and effort-down e1-lt))))) + (effort-up + (or e1-gt (and (equal e1 e2) p1-gt))) + (effort-down + (or e1-lt (and (equal e1 e2) p1-gt)))))))) + (when items + (goto-char (first (first items))) + (org-entry-add-to-multivalued-property nil "TRIGGER" tr) + (org-todo kwd))))))) ((string-match "\\`chain-siblings(\\(.*?\\))\\'" tr) ;; This is a TODO chain of siblings (setq kwd (match-string 1 tr)) (org-depend-act-on-sibling (format "chain-siblings(%s)" kwd) (org-todo kwd))) - ((string-match "\\`\\(\\S-+\\)(\\(.*?\\))\\'" tr) ;; This seems to be ENTRY_ID(KEYWORD) (setq id (match-string 1 tr) -- 1.7.3.4 [-- Attachment #2: Type: text/plain, Size: 1 bytes --] [-- Attachment #3: org-depend-chain-find-next-test.org --] [-- Type: application/octet-stream, Size: 2576 bytes --] #+TODO: TODO NEXT | DONE CANCELED * Default ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT) :END: ** TODO Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-top (same as default) ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-top) :END: ** TODO Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-bottom ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-bottom) :END: ** TODO Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-current,priority-up ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO [#A] Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current,priority-up) :END: ** TODO Item 6 ** Item 7 ** TODO [#B] Item 8 ** DONE Item 9 * from-current,no-wrap,priority-up ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO [#A] Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current,no-wrap,priority-up) :END: ** TODO Item 6 ** Item 7 ** TODO [#B] Item 8 ** DONE Item 9 * from-current, without todo-only ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current) :END: ** Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-current, with todo-only ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current,todo-only) :END: ** Item 6 ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-current without include-done ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current) :END: ** DONE Item 6 CLOSED: [2011-07-26 Tue 17:49] ** Item 7 ** TODO Item 8 ** DONE Item 9 * from-current with include-done ** TODO Item 1 ** TODO Item 2 ** TODO Item 3 ** TODO Item 4 ** NEXT Item 5 Current (mark me done) :PROPERTIES: :TRIGGER: chain-find-next(NEXT,from-current,todo-and-done-only) :END: ** DONE Item 6 CLOSED: [2011-07-26 Tue 17:49] ** Item 7 ** TODO Item 8 ** DONE Item 9 * end ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] New org-depend trigger for finding next highest priority/effort item 2011-07-26 23:34 ` Max Mikhanosha @ 2011-07-27 11:33 ` Bastien 0 siblings, 0 replies; 10+ messages in thread From: Bastien @ 2011-07-27 11:33 UTC (permalink / raw) To: Max Mikhanosha; +Cc: emacs-orgmode Hi Max, Max Mikhanosha <max@openchat.com> writes: > Amended patch attached, changes: > > - use (eval-when-compile) with require 'cl > - changed include-done to todo-and-done-only > - Added defcustom org-depend-find-next-options for default options > which are now: from-current,todo-only,priority-up > - cleaned up documentation Great. Applied, thanks for the fast rewrite! -- Bastien ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-07-28 8:07 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-07-24 18:58 [PATCH] New org-depend trigger for finding next highest priority/effort item Max Mikhanosha 2011-07-26 11:48 ` Bastien 2011-07-26 12:52 ` Sebastien Vauban 2011-07-26 14:59 ` Bastien 2011-07-26 21:56 ` Max Mikhanosha 2011-07-27 11:33 ` Bastien 2011-07-27 19:45 ` Max Mikhanosha 2011-07-28 7:11 ` Bastien 2011-07-26 23:34 ` Max Mikhanosha 2011-07-27 11:33 ` 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).