Browse Source

Agenda filter: Filter for entries with no effort defined

During secondary agenda filtering, pressing "?" now will install a
filter that selects entries which do not have an effort defined.

This new model was necessary because we needed to stop interpreting
entries with no effort defines as 0 effort.  This was inconsistent,
because for normal agenda sorting, the treatment of these entries
depends on the variable `org-sort-agenda-noeffort-is-high'.  Now this
variable is also respected during filtering.
Carsten Dominik 16 years ago
parent
commit
b16747b21c
4 changed files with 50 additions and 24 deletions
  1. 5 0
      doc/ChangeLog
  2. 11 7
      doc/org.texi
  3. 6 0
      lisp/ChangeLog
  4. 28 17
      lisp/org-agenda.el

+ 5 - 0
doc/ChangeLog

@@ -1,3 +1,8 @@
+2009-03-31  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org.texi (Agenda commands): Document the "?" operator to find
+	tasks without effort setting.
+
 2009-03-30  Carsten Dominik  <carsten.dominik@gmail.com>
 2009-03-30  Carsten Dominik  <carsten.dominik@gmail.com>
 
 
 	* org.texi (Exporting agenda information): Section moved.
 	* org.texi (Exporting agenda information): Section moved.

+ 11 - 7
doc/org.texi

@@ -6790,19 +6790,23 @@ requiring or forbidding the selected additional tag.  Instead of pressing
 @kbd{+} or @kbd{-} after @kbd{/}, you can also immediately use the @kbd{\}
 @kbd{+} or @kbd{-} after @kbd{/}, you can also immediately use the @kbd{\}
 command.
 command.
 
 
+@vindex org-sort-agenda-noeffort-is-high
 In order to filter for effort estimates, you should set-up allowed
 In order to filter for effort estimates, you should set-up allowed
 efforts globally, for example
 efforts globally, for example
 @lisp
 @lisp
 (setq org-global-properties
 (setq org-global-properties
     '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00")))
     '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00")))
 @end lisp
 @end lisp
-You can then filter for an effort by first typing an operator, one of @kbd{<},
-@kbd{>}, and @kbd{=}, and then the one-digit index of an effort estimate in
-your array of allowed values, where @kbd{0} means the 10th value.  The filter
-will then restrict to entries with effort smaller-or-equal, equal, or
-larger-or-equal than the selected value.  If the digits 0-9 are not used as
-fast access keys to tags, you can also simply press the index digit directly
-without an operator.  In this case, @kbd{<} will be assumed.
+You can then filter for an effort by first typing an operator, one of
+@kbd{<}, @kbd{>}, and @kbd{=}, and then the one-digit index of an effort
+estimate in your array of allowed values, where @kbd{0} means the 10th value.
+The filter will then restrict to entries with effort smaller-or-equal, equal,
+or larger-or-equal than the selected value.  If the digits 0-9 are not used
+as fast access keys to tags, you can also simply press the index digit
+directly without an operator.  In this case, @kbd{<} will be assumed.  For
+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.
 
 
 @kindex \
 @kindex \
 @item \
 @item \

+ 6 - 0
lisp/ChangeLog

@@ -1,5 +1,11 @@
 2009-03-31  Carsten Dominik  <carsten.dominik@gmail.com>
 2009-03-31  Carsten Dominik  <carsten.dominik@gmail.com>
 
 
+	* org-agenda.el (org-agenda-compare-effort): Honor
+	`org-sort-agenda-noeffort-is-high'.
+	(org-agenda-filter-by-tag, org-agenda-filter-make-matcher)
+	(org-agenda-compare-effort): Implement the "?" operator for
+	finding entries without effort setting.
+
 	* org.el (org-extract-attributes-from-string): New function.
 	* org.el (org-extract-attributes-from-string): New function.
 
 
 	* org-exp.el (org-export-splice-attributes): New function.
 	* org-exp.el (org-export-splice-attributes): New function.

+ 28 - 17
lisp/org-agenda.el

@@ -930,6 +930,9 @@ agenda entries."
 
 
 (defcustom org-sort-agenda-noeffort-is-high t
 (defcustom org-sort-agenda-noeffort-is-high t
   "Non-nil means, items without effort estimate are sorted as high effort.
   "Non-nil means, items without effort estimate are sorted as high effort.
+This also applies when filtering an agenda view with respect to the
+< or > effort operator.  Then, tasks with no effort defined will be treated
+as tasks with high effort.
 When nil, such items are sorted as 0 minutes effort."
 When nil, such items are sorted as 0 minutes effort."
   :group 'org-agenda-sorting
   :group 'org-agenda-sorting
   :type 'boolean)
   :type 'boolean)
@@ -4650,7 +4653,7 @@ to switch to narrowing."
 	char a n tag)
 	char a n tag)
     (unless char
     (unless char
       (message
       (message
-       "%s by tag [%s ], [TAB], [/]:off, [+-]:narrow, [>=<]:effort: "
+       "%s by tag [%s ], [TAB], [/]:off, [+-]:narrow, [>=<?]:effort: "
        (if narrow "Narrow" "Filter") tag-chars)
        (if narrow "Narrow" "Filter") tag-chars)
       (setq char (read-char)))
       (setq char (read-char)))
     (when (member char '(?+ ?-))
     (when (member char '(?+ ?-))
@@ -4660,20 +4663,21 @@ to switch to narrowing."
       (message
       (message
        "Narrow by tag [%s ], [TAB], [/]:off, [>=<]:effort: " tag-chars)
        "Narrow by tag [%s ], [TAB], [/]:off, [>=<]:effort: " tag-chars)
       (setq char (read-char)))
       (setq char (read-char)))
-    (when (member char '(?< ?> ?=))
+    (when (member char '(?< ?> ?= ??))
       ;; An effort operator
       ;; An effort operator
       (setq effort-op (char-to-string char))
       (setq effort-op (char-to-string char))
-      (loop for i from 0 to 9 do
-	    (setq effort-prompt
-		  (concat
-		   effort-prompt " ["
-		   (if (= i 9) "0" (int-to-string (1+ i)))
-		   "]" (nth i efforts))))
       (setq alist nil) ; to make sure it will be interpreted as effort.
       (setq alist nil) ; to make sure it will be interpreted as effort.
-      (message "Effort%s: %s " effort-op effort-prompt)
-      (setq char (read-char))
-      (when (or (< char ?0) (> char ?9))
-	(error "Need 1-9,0 to select effort" )))
+      (unless (equal char ??)
+	(loop for i from 0 to 9 do
+	      (setq effort-prompt
+		    (concat
+		     effort-prompt " ["
+		     (if (= i 9) "0" (int-to-string (1+ i)))
+		     "]" (nth i efforts))))
+	(message "Effort%s: %s " effort-op effort-prompt)
+	(setq char (read-char))
+	(when (or (< char ?0) (> char ?9))
+	  (error "Need 1-9,0 to select effort" ))))
     (when (equal char ?\t)
     (when (equal char ?\t)
       (unless (local-variable-p 'org-global-tags-completion-table (current-buffer))
       (unless (local-variable-p 'org-global-tags-completion-table (current-buffer))
 	(org-set-local 'org-global-tags-completion-table
 	(org-set-local 'org-global-tags-completion-table
@@ -4692,6 +4696,9 @@ to switch to narrowing."
 	       (setq n (if (= char ?0) 9 (- char ?0 1))
 	       (setq n (if (= char ?0) 9 (- char ?0 1))
 		     tag (concat effort-op (nth n efforts))
 		     tag (concat effort-op (nth n efforts))
 		     a (cons tag nil)))
 		     a (cons tag nil)))
+	  (and (= char ??)
+	       (setq tag "?eff")
+	       a (cons tag nil))
 	  (and tag (setq a (cons tag nil))))
 	  (and tag (setq a (cons tag nil))))
       (org-agenda-filter-by-tag-show-all)
       (org-agenda-filter-by-tag-show-all)
       (setq tag (car a))
       (setq tag (car a))
@@ -4713,7 +4720,7 @@ to switch to narrowing."
 		       org-agenda-filter))
 		       org-agenda-filter))
       (if (member x '("-" "+"))
       (if (member x '("-" "+"))
 	  (setq f1 '(not tags))
 	  (setq f1 '(not tags))
-	(if (string-match "[<=>]" x)
+	(if (string-match "[<=>?]" x)
 	    (setq f1 (org-agenda-filter-effort-form x))
 	    (setq f1 (org-agenda-filter-effort-form x))
 	  (setq f1 (list 'member (downcase (substring x 1)) 'tags)))
 	  (setq f1 (list 'member (downcase (substring x 1)) 'tags)))
 	(if (equal (string-to-char x) ?-)
 	(if (equal (string-to-char x) ?-)
@@ -4727,7 +4734,10 @@ E looks line \"+<2:25\"."
   (let (op)
   (let (op)
     (setq e (substring e 1))
     (setq e (substring e 1))
     (setq op (string-to-char e) e (substring e 1))
     (setq op (string-to-char e) e (substring e 1))
-    (setq op (if (equal op ?<) '<= (if (equal op ?>) '>= '=)))
+    (setq op (cond ((equal op ?<) '<=)
+		   ((equal op ?>) '>=)
+		   ((equal op ??) op)
+		   (t '=)))
     (list 'org-agenda-compare-effort (list 'quote op)
     (list 'org-agenda-compare-effort (list 'quote op)
 	  (org-hh:mm-string-to-minutes e))))
 	  (org-hh:mm-string-to-minutes e))))
 
 
@@ -4735,9 +4745,10 @@ E looks line \"+<2:25\"."
   "Compare the effort of the current line with VALUE, using OP.
   "Compare the effort of the current line with VALUE, using OP.
 If the line does not have an effort defined, return nil."
 If the line does not have an effort defined, return nil."
   (let ((eff (get-text-property (point) 'effort-minutes)))
   (let ((eff (get-text-property (point) 'effort-minutes)))
-    (if (not eff)
-	0 ; we don't have an effort defined, treat as 0
-      (funcall op eff value))))
+    (if (equal op ??)
+	(not eff)
+      (funcall op (or eff (if org-sort-agenda-noeffort-is-high 32767 0))
+	       value))))
 
 
 (defun org-agenda-filter-apply (filter)
 (defun org-agenda-filter-apply (filter)
   "Set FILTER as the new agenda filter and apply it."
   "Set FILTER as the new agenda filter and apply it."