emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Greg Tucker-Kellogg <gtuckerkellogg@gmail.com>
To: org-mode mailing list <emacs-orgmode@gnu.org>
Subject: [PATCH] Making org-agenda filters orthogonal and refreshed
Date: Sat, 19 Apr 2014 09:53:08 +0800	[thread overview]
Message-ID: <CAFxtbJDeyfq+rMJxEOZApze5LH=o+OKEHdO5+=z--9Y9XLfuFg@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1733 bytes --]

This is org-mode version 8.2.5h, directly off the git.
emacs version 24.4.50.1

I have noticed that combining top headline filters and category
filters didn't always work as documented.  In particular, the
combination of filters displayed depends on the order of application
and removal, and is not always refreshed properly.  To test it, I
created a new org file with a couple of simple entries.  Note: the
behaviour is most obvious if you have some other tasks with the same
categories or tags in your global todo agenda.

* A team member

** TODO Task 1                                                     :COMPUTER:
:PROPERTIES:
:CATEGORY: Work
:END:

** TODO Task 2
:PROPERTIES:
:CATEGORY: Team
:END:

* Someone else

** TODO Someone else's Task 1                                      :COMPUTER:
:PROPERTIES:
:CATEGORY: Work
:END:


If I apply two filters in succession: "^" to filter to the "top
headline" and "<" to filter to the "Work" category, it appears to
work.  But then if I toggle the top headline filter with "^" again,
all the filters are removed, because the function is using the
category filter type to apply and remove the top headline overlay.
(Separately, the "|" shortcut to remove all filters does not currently
recognise a top headline filter).

I created a patch to fix the issues, but I think it's a bit of a hack,
and I'd welcome input or a better patch by a more skilled coder.  Even
after separating the filter removal, I ended up advising two filter
functions to reload the agenda so that it refreshed properly.  All of
this reflects my poor elisp skills.  Nonetheless, I  wonder if
org-agenda doesn't need some refactoring to remove the explicit
repetition of cases for different filter types.

Greg

[-- Attachment #2: org-agenda.el.diff --]
[-- Type: text/plain, Size: 4623 bytes --]

diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 184209b..d686bd7 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -2097,6 +2097,7 @@ When nil, `q' will kill the single agenda buffer."
     org-agenda-tag-filter
     org-agenda-cat-filter-overlays
     org-agenda-category-filter
+    org-agenda-top-headline-filter
     org-agenda-re-filter-overlays
     org-agenda-regexp-filter
     org-agenda-markers
@@ -3412,6 +3413,7 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
 
 (defvar org-agenda-tag-filter-overlays nil)
 (defvar org-agenda-cat-filter-overlays nil)
+(defvar org-agenda-top-headline-filter-overlays nil)
 (defvar org-agenda-re-filter-overlays nil)
 
 (defun org-agenda-mark-filtered-text ()
@@ -3425,6 +3427,7 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
 	  'org-filtered t)))
      (append org-agenda-tag-filter-overlays
 	     org-agenda-cat-filter-overlays
+	     org-agenda-top-headline-filter-overlays
 	     org-agenda-re-filter-overlays))))
 
 (defun org-agenda-unmark-filtered-text ()
@@ -7352,6 +7355,11 @@ The category is that of the current line."
 	       (list (concat "+" cat))) 'category))
        ((error "No category at point"))))))
 
+ 
+(defadvice org-agenda-filter-by-category (after org-agenda-redo-after-cat-filter activate)
+  "sometimes the filter needs to be redone"
+  (org-agenda-redo))
+
 (defun org-find-top-headline (&optional pos)
   "Find the topmost parent headline and return it."
   (save-excursion
@@ -7371,10 +7379,14 @@ The top headline is that of the current line."
       (progn
         (setq org-agenda-filtered-by-top-headline nil
 	      org-agenda-top-headline-filter nil)
-        (org-agenda-filter-show-all-cat))
-    (let ((cat (org-find-top-headline (org-get-at-bol 'org-hd-marker))))
-      (if cat (org-agenda-filter-top-headline-apply cat strip)
-        (error "No top-level category at point")))))
+        (org-agenda-filter-show-all-top-headlines))
+    (let ((tophl (org-find-top-headline (org-get-at-bol 'org-hd-marker))))
+      (if tophl (org-agenda-filter-top-headline-apply tophl strip)
+        (error "No top-level headline at point")))))
+
+(defadvice org-agenda-filter-by-top-headline (after org-agenda-redo-after-tophl-filter activate)
+  "sometimes the filter needs to be redone"
+  (org-agenda-redo))
 
 (defvar org-agenda-regexp-filter nil)
 (defun org-agenda-filter-by-regexp (strip)
@@ -7403,7 +7415,9 @@ With two prefix arguments, remove the regexp filters."
   (when org-agenda-category-filter
     (org-agenda-filter-show-all-cat))
   (when org-agenda-regexp-filter
-    (org-agenda-filter-show-all-re)))
+    (org-agenda-filter-show-all-re))
+  (when org-agenda-top-headline-filter)
+  (org-agenda-filter-show-all-top-headlines))
 
 (defun org-agenda-filter-by-tag (strip &optional char narrow)
   "Keep only those lines in the agenda buffer that have a specific tag.
@@ -7665,7 +7679,7 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
              (tophl (and pos (org-find-top-headline pos))))
         (if (and tophl (funcall (if negative 'identity 'not)
 				(string= hl tophl)))
-            (org-agenda-filter-hide-line 'category)))
+            (org-agenda-filter-hide-line 'headline)))
       (beginning-of-line 2)))
   (if (get-char-property (point) 'invisible)
       (org-agenda-previous-line))
@@ -7682,6 +7696,7 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
     (overlay-put ov 'type type)
     (cond ((eq type 'tag) (push ov org-agenda-tag-filter-overlays))
 	  ((eq type 'category) (push ov org-agenda-cat-filter-overlays))
+	  ((eq type 'headline) (push ov org-agenda-top-headline-filter-overlays))
 	  ((eq type 'regexp) (push ov org-agenda-re-filter-overlays)))))
 
 (defun org-agenda-fix-tags-filter-overlays-at (&optional pos)
@@ -7720,6 +7735,15 @@ When NO-OPERATOR is non-nil, do not add the + operator to returned tags."
 	org-agenda-filter-form nil)
   (org-agenda-set-mode-name))
 
+(defun org-agenda-filter-show-all-top-headlines nil
+  "Remove top headline filter overlays from the agenda buffer."
+  (mapc 'delete-overlay org-agenda-top-headline-filter-overlays)
+  (setq org-agenda-top-headline-filter-overlays nil
+	org-agenda-filtered-by-top-headline nil
+	org-agenda-top-headline-filter nil
+	org-agenda-filter-form nil)
+  (org-agenda-set-mode-name))
+
 (defun org-agenda-manipulate-query-add ()
   "Manipulate the query by adding a search term with positive selection.
 Positive selection means the term must be matched for selection of an entry."

             reply	other threads:[~2014-04-19  1:53 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-19  1:53 Greg Tucker-Kellogg [this message]
2014-04-19  6:02 ` [PATCH] Making org-agenda filters orthogonal and refreshed Bastien
2014-04-19  8:53   ` Greg Tucker-Kellogg
2014-04-19  9:06     ` Bastien
2014-05-22 11:39 ` Bastien

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFxtbJDeyfq+rMJxEOZApze5LH=o+OKEHdO5+=z--9Y9XLfuFg@mail.gmail.com' \
    --to=gtuckerkellogg@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).