From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Wiegley Subject: Filtering agenda by the "top" category Date: Wed, 04 Apr 2012 15:38:55 -0500 Message-ID: Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([208.118.235.92]:50563) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFWzH-0000Qy-3k for emacs-orgmode@gnu.org; Wed, 04 Apr 2012 16:39:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SFWz7-00063E-L1 for emacs-orgmode@gnu.org; Wed, 04 Apr 2012 16:39:24 -0400 Received: from plane.gmane.org ([80.91.229.3]:54919) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFWz7-00062r-Dj for emacs-orgmode@gnu.org; Wed, 04 Apr 2012 16:39:17 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1SFWz1-0006pw-W7 for emacs-orgmode@gnu.org; Wed, 04 Apr 2012 22:39:12 +0200 Received: from c-98-215-105-167.hsd1.il.comcast.net ([98.215.105.167]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 04 Apr 2012 22:39:11 +0200 Received: from jwiegley by c-98-215-105-167.hsd1.il.comcast.net with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 04 Apr 2012 22:39:11 +0200 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: emacs-orgmode@gnu.org Cc: Dave Abrahams I discovered the < key in the agenda yesterday (by accident!), which filters the Agenda down to entries having the same category. However, I use both *categories* and *projects*. For example: * Work :CATEGORY: Work :OVERLAY: (face (:background "#fdfdeb")) ** PROJECT Foo :CATEGORY: Foo I use :CATEGORY: for my project here so it shows up in the leftmost column of my agenda. I don't want every project displaying as just "Work". I use the :OVERLAY: so that all Work items have the same background color, which is a better way of seeing at a glance which *category* every item falls into. What this means is that although I can use < to filter by *project*, I can't filter down to the "Work" *category*. So that's what the code below does. I bind it to >, since I wasn't using what that binding does. Also, I found a bug: passing a prefix argument to < doesn't have any effect. The code doesn't use that argument in any meaningful way. John (define-key org-agenda-mode-map ">" 'org-agenda-filter-by-top-category) (defun org-find-top-category (&optional pos) (save-excursion (with-current-buffer (if pos (marker-buffer pos) (current-buffer)) (if pos (goto-char pos)) ;; Skip up to the topmost parent (while (ignore-errors (outline-up-heading 1) t)) (ignore-errors (nth 4 (org-heading-components)))))) (defvar org-agenda-filtered-by-top-category nil) (defun org-agenda-filter-by-top-category (strip) "Keep only those lines in the agenda buffer that have a specific category. The category is that of the current line." (interactive "P") (if org-agenda-filtered-by-top-category (progn (setq org-agenda-filtered-by-top-category nil) (org-agenda-filter-show-all-cat)) (let ((cat (org-find-top-category (org-get-at-bol 'org-hd-marker)))) (if cat (org-agenda-filter-top-category-apply cat) (error "No top-level category at point"))))) (defun org-agenda-filter-top-category-apply (category) "Set FILTER as the new agenda filter and apply it." (org-agenda-set-mode-name) (save-excursion (goto-char (point-min)) (while (not (eobp)) (let* ((pos (org-get-at-bol 'org-hd-marker)) (topcat (and pos (org-find-top-category pos)))) (if (and topcat (not (string= category topcat))) (org-agenda-filter-hide-line 'category))) (beginning-of-line 2))) (if (get-char-property (point) 'invisible) (org-agenda-previous-line)) (setq org-agenda-filtered-by-top-category t))