Search code examples
emacsorg-mode

Org-mode: Filter on tag in agenda view?


Is it possible to filter on tags when agenda constructs its view? I have tried the following to show only work related appointments:

("j" "Jobb"
   ((agenda ""
       ((org-agenda-skip-function '(org-agenda-skip-entry-if 'notregexp":jobb:"))))
    (tags-todo "jobb"))
    ((org-agenda-compact-blocks nil)))

This works only if the actual appointment is directly tagged, but not if the appointment inherits its tag from a parent headline like this:

 * Tider                                                              :jobb:                                                                                                                                                         
 ** Millas arbetstider                                                                                                                                                                                                               
   <2012-04-11 ons 05:00-09:00>                                                                                                                                                                                                     
   <2012-04-12 tor 04:15-08:30>                                                                                                                                                                                                     
   <2012-04-13 fre 14:30-18:30>                           

Is there another way to do this so that appointments that inherits its tag shows up?


Solution

  • The issue is in how org-agenda-skip-entries-if interacts with 'notregexp. It will skip any entries that do not match :jobb:. Even though the later entries inherit the tag, it is not explicitly listed and so they are skipped. There also does not seem to be any built-in method to match (or not match) on tags using org-agenda-skip-entries-if. If there is such a function it would likely be the more efficient method of looking for the tags, but I'm not aware of such a function.

    You instead have to create a custom function that will provide the desired search-format.

    If you change your agenda command to:

    ("j" "Jobb"
             ((agenda ""
                      ((org-agenda-skip-function '(zin/org-agenda-skip-tag "jobb" 't))))
              (tags-todo "jobb"))
             ((org-agenda-compact-blocks nil)))
    

    and define zin/org-agenda-skip-tag as:

    (defun zin/org-agenda-skip-tag (tag &optional others)
      "Skip all entries that correspond to TAG.
    
    If OTHERS is true, skip all entries that do not correspond to TAG."
      (let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))
            (current-headline (or (and (org-at-heading-p)
                                       (point))
                                  (save-excursion (org-back-to-heading)))))
        (if others
            (if (not (member tag (org-get-tags-at current-headline)))
                next-headline
              nil)
          (if (member tag (org-get-tags-at current-headline))
              next-headline
            nil))))
    

    You will get what I understand to be your desired agenda view. If I have it backwards and the entries on the next 3 days should not be present, you simply have to change the function to (zin/org-agenda-skip-tag "jobb") or (zin/org-agenda-skip-tag "jobb" 'nil), they are equivalent in this case.

    Agenda View

    In this case test-new is the name of the org-file I was using, it can be ignored. I also set both headlines to TODO to have them visible when testing the function, since I was restricting the agenda to only the one file.

    Week-agenda (W15):
    Monday      9 April 2012 W15
    Tuesday    10 April 2012
    Wednesday  11 April 2012
      test-new:    5:00- 9:00 TODO Millas arbetstider                        :jobb::
    Thursday   12 April 2012
      test-new:    4:15- 8:30 TODO Millas arbetstider                        :jobb::
    Friday     13 April 2012
      test-new:   14:30-18:30 TODO Millas arbetstider                        :jobb::
    Saturday   14 April 2012
    Sunday     15 April 2012
    
    ================================================================================
    Headlines with TAGS match: jobb
      test-new:   TODO Tider                                                  :jobb:
      test-new:   TODO Millas arbetstider                                    :jobb::