From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nick Dokos Subject: Re: Setting a task's priority based on its subtasks priorities Date: Fri, 13 Apr 2012 00:35:09 -0400 Message-ID: <3582.1334291709@alphaville> References: Reply-To: nicholas.dokos@hp.com Return-path: Received: from eggs.gnu.org ([208.118.235.92]:42595) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SIYE8-0008MH-Hw for emacs-orgmode@gnu.org; Fri, 13 Apr 2012 00:35:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SIYE6-0000OD-8P for emacs-orgmode@gnu.org; Fri, 13 Apr 2012 00:35:16 -0400 Received: from g1t0027.austin.hp.com ([15.216.28.34]:30256) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SIYE6-0000O3-0d for emacs-orgmode@gnu.org; Fri, 13 Apr 2012 00:35:14 -0400 In-Reply-To: Message from "Filippo A. Salustri" of "Thu, 12 Apr 2012 20:55:42 EDT." List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: "Filippo A. Salustri" Cc: emacs-orgmode mailing list Filippo A. Salustri wrote: > Hi all, > I'm looking for a little coding help. > > I want to try to a task's priority automatically, based on the priorities of its subtasks. > Specifically, I'd like to set the priority of the task to the priority of the highest-priority > subtask. > And I'd like that task priority to be updated (if necessary) automatically any time I change the > priority of one of its subtasks. > The basic idea in all of these situations is to use org-map-entries from the mapping API: (info "(org) Using the mapping API") to walk the entries, applying a function on each. The function to apply on each entry is frequently a specialization of one of the functions provided by the property API: (info "(org) Using the property API") In this case, you need a function to get the priority of each entry: (def fas/task-priority () (org-entry-get (point) "PRIORITY")) which you can then give to org-map-entries: (org-map-entries (function fas/task-priority) t 'tree) The assumption here is that we are at the head node and we have an arbitrary number of subnodes. The call above will accumulate the priorities of each subnode in a list (if a subnode does not have a priority assigned, the priority will be nil). For example, applying * section ** [#B] subsection *** [#C] subsubsection **** paragraph ***** [#B] subparagraph will return the list (nil "B" "C" nil "B") It is then just a matter of finding the highest priority and applying it to the top node. Assuming that "A" is higher priority than "B" etc, something like this will do: --8<---------------cut here---------------start------------->8--- (defun fas/task-priority () (org-entry-get (point) "PRIORITY")) (defun fas/set-task-priority () (interactive) (let* ((priorities (org-map-entries (function fas/task-priority) t 'tree)) (sortedpriorities (sort (delq nil priorities) (function string-lessp)))) (if sortedpriorities (org-priority (aref (car sortedpriorities) 0))))) --8<---------------cut here---------------end--------------->8--- org-priority wants a character, but sortedpriorities is a list of strings, hence the aref rigmarole. It should work even if *no* priorities are set at all: sortedpriorities will be nil, so nothing will be done. Nick