From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Peter Westlake" Subject: Searching for tags or todo keywords Date: Fri, 22 Aug 2008 14:21:01 +0100 Message-ID: <1219411261.28705.1269971211@webmail.messagingengine.com> Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7bit Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KWWdM-0008E0-Cf for emacs-orgmode@gnu.org; Fri, 22 Aug 2008 09:24:56 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KWWdK-0008Ci-AF for emacs-orgmode@gnu.org; Fri, 22 Aug 2008 09:24:55 -0400 Received: from [199.232.76.173] (port=43789 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KWWdK-0008CW-1g for emacs-orgmode@gnu.org; Fri, 22 Aug 2008 09:24:54 -0400 Received: from mx20.gnu.org ([199.232.41.8]:52836) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KWWdJ-0006Of-Pe for emacs-orgmode@gnu.org; Fri, 22 Aug 2008 09:24:53 -0400 Received: from out3.smtp.messagingengine.com ([66.111.4.27]) by mx20.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KWWdI-000694-Rh for emacs-orgmode@gnu.org; Fri, 22 Aug 2008 09:24:53 -0400 Received: from compute1.internal (compute1.internal [10.202.2.41]) by out1.messagingengine.com (Postfix) with ESMTP id 8C397141BD6 for ; Fri, 22 Aug 2008 09:21:01 -0400 (EDT) Content-Disposition: inline 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: emacs-orgmode@gnu.org I only discovered org-mode a couple of weeks ago, so apologies if this is a FAQ, or the patch is in the wrong format. I would like to define an agenda command to show TODO items in the context of the projects to which they belong, like this: todo: .Widget project todo: ..TODO Gather widget requirements todo: .Gadget project todo: ..TODO Plan the end of project party That would be a search like: (LEVEL=2) | (/TODO) But LEVEL=2|/TODO is interpreted as (LEVEL=2|) & (/TODO) because / has the lowest precedence. /TODO|LEVEL=2 treats LEVEL as a TODO word instead of a tag. Is there any way around this, short of implementing parentheses? One possibility might be to make operators that are like / but bind most tightly, one to say "this is a todo keyword" and one to say "this is a tag". For instance, if \ was like / but high precedence, and % was the opposite of \, my query would become: \TODO | %LEVEL=2 Having looked at the code, that looks almost as hard as parens. Next idea: since "/" means "and this TODO expression", add "\" meaning "or this TODO expression". So my query becomes: LEVEL=2\TODO This is a lot easier to implement. In fact, this patch does it: diff -wu /usr/share/emacs/site-lisp/org-mode/org.el /home/pwestlake/elisp/org.el --- /usr/share/emacs/site-lisp/org-mode/org.el 2008-06-17 20:36:44.000000000 +0100 +++ /home/pwestlake/elisp/org.el 2008-08-22 14:13:44.031536000 +0100 @@ -9381,17 +9381,26 @@ tagsmatch todomatch tagsmatcher todomatcher kwd matcher orterms term orlist re-p str-p level-p level-op prop-p pn pv po cat-p gv) - (if (string-match "/+" match) + (cond ((string-match "/+" match) ;; match contains also a todo-matching request - (progn (setq tagsmatch (substring match 0 (match-beginning 0)) todomatch (substring match (match-end 0))) (if (string-match "^!" todomatch) (setq todo-only t todomatch (substring todomatch 1))) (if (string-match "^\\s-*$" todomatch) - (setq todomatch nil))) + (setq todomatch nil)) + (setq todo-op 'and todo-op-default t)) + ((string-match "\\\\+" match) + (setq tagsmatch (substring match 0 (match-beginning 0)) + todomatch (substring match (match-end 0))) + (if (string-match "^!" todomatch) + (setq todo-only t todomatch (substring todomatch 1))) + (if (string-match "^\\s-*$" todomatch) + (setq todomatch nil)) + (setq todo-op 'or todo-op-default nil)) + ;; only matching tags - (setq tagsmatch match todomatch nil)) + (t (setq tagsmatch match todomatch nil todo-op-default t todo-op 'and))) ;; Make the tags matcher (if (or (not tagsmatch) (not (string-match "\\S-" tagsmatch))) @@ -9447,7 +9456,7 @@ (list 'progn '(setq org-cached-props nil) tagsmatcher))) ;; Make the todo matcher (if (or (not todomatch) (not (string-match "\\S-" todomatch))) - (setq todomatcher t) + (setq todomatcher todo-op-default) (setq orterms (org-split-string todomatch "|") orlist nil) (while (setq term (pop orterms)) (while (string-match re term) @@ -9471,7 +9480,7 @@ ;; Return the string and lisp forms of the matcher (setq matcher (if todomatcher - (list 'and tagsmatcher todomatcher) + (list todo-op tagsmatcher todomatcher) tagsmatcher)) (cons match0 matcher))) Regards, Peter.