From mboxrd@z Thu Jan 1 00:00:00 1970 From: Carsten Dominik Subject: TODO dependencies Date: Fri, 19 Oct 2007 08:27:08 +0200 Message-ID: Mime-Version: 1.0 (Apple Message framework v624) Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IilKA-0005qz-GQ for emacs-orgmode@gnu.org; Fri, 19 Oct 2007 02:27:10 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IilK9-0005py-V6 for emacs-orgmode@gnu.org; Fri, 19 Oct 2007 02:27:10 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IilK9-0005pn-FE for emacs-orgmode@gnu.org; Fri, 19 Oct 2007 02:27:09 -0400 Received: from korteweg.uva.nl ([146.50.98.70]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1IilK9-0003fQ-3i for emacs-orgmode@gnu.org; Fri, 19 Oct 2007 02:27:09 -0400 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: org-mode mailing list On Oct 11, 2007, at 16:46, Carsten Dominik wrote: > - concerning the TRIGGER proposal by John, and the TRIGGER/BLOCKER > functionality > discussed later: In Emacs terms, this seems to translate into a > *hook* > that is called at the right moment. I'd say that a single hook is > enough. > The right moment to call it would be when Org-mode has figured out > everything > about a change that is about to occur, but before actually doing it. > We can be general what kind of change this could be, a TODO state > change, > adding a tag, setting a property, changing the priority, anything > really. > So we would have a property that contains a Lisp form, and that lisp > form would > be evaluated at that moment. > TRIGGER would then mean to perform actions in other entries. > BLOCKER would mean to query other entries for information, and, if > necessary, > abort the current action, for example by throwing to a specified > catch form. > Obviously, if you nee both triggers and blockers, the blockers need > to run > first, but we don't need separate properties/functions for this. > > The detailed implementation would then be a number of Lisp functions > that > take as arguments a *single* structure that contains all the info of > the change, > for example a property list like > > (list :type 'TODOSTATE :from nil %to "INPROGRESS" .... Due to the controversial nature of the discussion on this subject, it seems to be better, for the time being, to keep this functionality outside the core of org-mode. Other reasons for this are that the free-form nature of Org-mode files do make it non-trivial to implement dependencies in a bullet-proof way. I will actually take still another step back from the proposals we discussed: I'd like to not even fix the properties that should be used for dependencies. Instead, I am proposing and starting up the following route: Org-mode version 5.13 contains two new hooks, `org-blocker-hook' and `org-trigger-hook'. These hooks are called before and after a state change, respectively. Currently only TODO state changes will do this, but more could be added in the future. The blocker hook is able to block a state change, the trigger hook just happens after the change. This is all that will go into the core for now. While this may seem little, it actually opens the dore wide for a number of dependency extensions to be written, with free choice of properties to be used and the "language" applied in these properties to describe dependencies. In this way we can have different implementations working alongside without conflicts. As a proof of concept, I am providing a small file org-depend.el. This is not meant as a definition of how things should be, but as an inspiration to people who want to try their teeth at this. Nevertheless, this small set of functions already does most of what at least some of you have been asking for: It introduces the concept of chaining a sequence of TODO entries together by insinuating only the first entry in the chain. It also allows for entries to be identified by an :ID: property, and this property to be used to trigger or be blocked by entries in arbitrary places in the current file. So I hope it will be a good starting point, I have tried to comment it well enough so that hacking should be easy. Here is a copy of the documentation from that file. The file itself is available at http://orgmode.el/org-depend.el. - Carsten ---8><--------------------------------------------------------><8------ WARNING: This file is just a PROOF OF CONCEPT, not a supported part of Org-mode. This is an example implementation of TODO dependencies in Org-mode. It uses the new hooks in version 5.13 of Org-mode, `org-trigger-hook' and `org-blocker-hook'. It implements the following: Triggering ---------- 1) If an entry contains a TRIGGER property that contains the word "chain-siblings", then switching that entry to DONE does the following: - The sibling following this entry is marked DONE. - The sibling also get the "chain-sibling" property, to make sure that, when *it* is DONE, the chain will continue. 2) If the TRIGGER property contains any other words, these are treated as entry id's. That means, Org-mode will search for an entry with the ID property exactly equal to this word, and switch that entry to TODO as well. Blocking -------- 1) If an entry contains a BLOCKER property that contains the word "previous-sibling", the sibling above the current entry is checked. If it is still in a TODO state, the current state change is blocked. 2) If the BLOCKER property contains any other words, these are treated as entry id's. That means, Org-mode will search for an entry with the ID property exactly equal to this word, and make sure that this entry is done as well, before allowing the state change to occur. Example: -------- When trying this example, make sure that the settings for TODO keywords have been activated, i.e. include the following line and press C-c C-c on the line before working with the example: * TODO Win a million in Las Vegas The "third" TODO (see above) cannot become a TODO without this money. :PROPERTIES: :ID: I-cannot-do-it-without-money :END: * Do this by doing a chain of TODO's ** TODO This is the first in this chain :PROPERTIES: :TRIGGER: chain-siblings :END: ** This is the second in this chain ** This is the third in this chain :PROPERTIES: :BLOCKER: I-cannot-do-it-without-money :END: ** This is the forth in this chain When this is DONE, we will also trigger entry XYZ-is-my-id :PROPERTIES: :TRIGGER: XYZ-is-my-id :END: ** This is the fifth in this chain * Write report :PROPERTIES: :ID: XYZ-is-my-id :END: