[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Orgmode] Searching for tags or todo keywords

From: Peter Westlake
Subject: [Orgmode] Searching for tags or todo keywords
Date: Fri, 22 Aug 2008 14:21:01 +0100

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:


This is a lot easier to implement. In fact, this patch does it:

diff -wu /usr/share/emacs/site-lisp/org-mode/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
@@ -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)
     (cons match0 matcher)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]