From 85878aadbf7229a5e0e9ce39cc1f1e313b67bb1a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 18 Oct 2009 23:41:26 -0400 Subject: [PATCH] Added context-aware, tag auto-exclusion (/ RET) (org-agenda-auto-exclude-function): New customization variable for allowing the user to create an "auto exclusion" filter for doing context-aware auto tag filtering. (org-agenda-filter-by-tag): Changes to support the use of `org-agenda-auto-exclude-function'. See the new manual addition,. --- doc/org.texi | 26 ++++++++++++++++++++++++ lisp/ChangeLog | 8 ++++++++ lisp/org-agenda.el | 49 +++++++++++++++++++++++++++++++++------------- 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index 67a3a109b..5ae657549 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -7224,6 +7224,32 @@ application of the operator, entries without a defined effort will be treated according to the value of @code{org-sort-agenda-noeffort-is-high}. To filter for tasks without effort definition, press @kbd{?} as the operator. +Org also supports automatic, context-aware tag filtering. If the variable +@code{org-agenda-auto-exclude-function} is set to a user-defined function, +that function can decide which tags should be excluded from the agenda +automatically. Once this is set, the @kbd{/} command then accepts @kbd{RET} +as a sub-option key and runs the auto exclusion logic. For example, let's +say you use a @code{Net} tag to identify tasks which need network access, an +@code{Errand} tag for errands in town, and a @code{Call} tag for making phone +calls. You could auto-exclude these tags based on the availability of the +Internet, and outside of business hours, with something like this: + +@lisp +@group +(defun org-my-auto-exclude-function (tag) + (and (cond + ((string= tag "Net") + (/= 0 (call-process "/sbin/ping" nil nil nil + "-c1" "-q" "-t1" "mail.gnu.org"))) + ((or (string= tag "Errand") (string= tag "Call")) + (let ((hour (nth 2 (decode-time)))) + (or (< hour 8) (> hour 21))))) + (concat "-" tag))) + +(setq org-agenda-auto-exclude-function 'org-my-auto-exclude-function) +@end group +@end lisp + @kindex \ @item \ Narrow the current agenda filter by an additional condition. When called with diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ee4dbe56a..c4373058a 100755 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,11 @@ +2009-10-19 John Wiegley + + * org-agenda.el (org-agenda-auto-exclude-function): New + customization variable for allowing the user to create an "auto + exclusion" filter for doing context-aware auto tag filtering. + (org-agenda-filter-by-tag): Changes to support the use of + `org-agenda-auto-exclude-function'. See the new manual addition,. + 2009-10-18 John Wiegley * org.el (org-files-list): Don't attempt to return a file name for diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index f6fa51a45..730250ba6 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -1276,6 +1276,15 @@ estimate." :group 'org-agenda-column-view :type 'boolean) +(defcustom org-agenda-auto-exclude-function nil + "A function called with a tag to decide if it is filtered on '/ RET'. +The sole argument to the function, which is called once for each +possible tag, is a string giving the name of the tag. The +function should return either nil if the tag should be included +as normal, or \"-\" to exclude the tag." + :group 'org-agenda + :type 'function) + (eval-when-compile (require 'cl)) (require 'org) @@ -5037,22 +5046,23 @@ used to narrow the search - the interactive user can also press `-' or `+' to switch to narrowing." (interactive "P") (let* ((alist org-tag-alist-for-agenda) - (tag-chars (mapconcat - (lambda (x) (if (cdr x) (char-to-string (cdr x)) "")) - alist "")) - (efforts (org-split-string - (or (cdr (assoc (concat org-effort-property "_ALL") - org-global-properties)) - "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00 8:00" ""))) - (effort-op org-agenda-filter-effort-default-operator) - (effort-prompt "") - (inhibit-read-only t) - (current org-agenda-filter) - char a n tag) + (tag-chars (mapconcat + (lambda (x) (if (cdr x) (char-to-string (cdr x)) "")) + alist "")) + (efforts (org-split-string + (or (cdr (assoc (concat org-effort-property "_ALL") + org-global-properties)) + "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00 8:00" ""))) + (effort-op org-agenda-filter-effort-default-operator) + (effort-prompt "") + (inhibit-read-only t) + (current org-agenda-filter) + char a n tag) (unless char (message - "%s by tag [%s ], [TAB], [/]:off, [+-]:narrow, [>==