Browse Source

org-agenda: Fix UI bug with effort filter

* lisp/org-agenda.el (org-agenda-filter-by-effort): "0" key
  effectively selects the last effort duration instead of the first
  one.  Do not accept invalid keys, i.e., do not treat most of invalid
  keys as "0".
Nicolas Goaziou 3 years ago
parent
commit
7419075e48
1 changed files with 35 additions and 25 deletions
  1. 35 25
      lisp/org-agenda.el

+ 35 - 25
lisp/org-agenda.el

@@ -7487,31 +7487,41 @@ With no prefix argument, keep entries matching the effort condition.
 With one prefix argument, filter out entries matching the condition.
 With two prefix arguments, remove the effort filters."
   (interactive "P")
-  (cond ((member strip '(nil 4))
-	 (let ((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"
-			     "")))
-	       (eff -1)
-	       effort-prompt op)
-	   (while (not (member op '(?< ?> ?=)))
-	     (setq op (read-char-exclusive "Effort operator? (> = or <)")))
-	   (cl-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" (char-to-string op) effort-prompt)
-	   (while (or (< eff 0) (> eff 9))
-	     (setq eff (string-to-number (char-to-string (read-char-exclusive)))))
-	   (setq org-agenda-effort-filter
-		 (list (concat (if strip "-" "+")
-			       (char-to-string op) (nth (1- eff) efforts))))
-	   (org-agenda-filter-apply org-agenda-effort-filter 'effort)))
-	(t (org-agenda-filter-show-all-effort)
-	   (message "Effort filter removed"))))
+  (cond
+   ((member strip '(nil 4))
+    (let* ((efforts (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")))
+	   ;; XXX: the following handles only up to 10 different
+	   ;; effort values.
+	   (allowed-keys (if (null efforts) nil
+			   (mapcar (lambda (n) (mod n 10)) ;turn 10 into 0
+				   (number-sequence 1 (length efforts)))))
+	   (op nil))
+      (while (not (memq op '(?< ?> ?=)))
+	(setq op (read-char-exclusive "Effort operator? (> = or <)")))
+      ;; Select appropriate duration.  Ignore non-digit characters.
+      (let ((prompt
+	     (apply #'format
+		    (concat "Effort %c "
+			    (mapconcat (lambda (s) (concat "[%d]" s))
+				       efforts
+				       " "))
+		    op allowed-keys))
+	    (eff -1))
+	(while (not (memq eff allowed-keys))
+	  (message prompt)
+	  (setq eff (- (read-char-exclusive) 48)))
+	(setq org-agenda-effort-filter
+	      (list (concat (if strip "-" "+")
+			    (char-to-string op)
+			    ;; Numbering is 1 2 3 ... 9 0, but we want
+			    ;; 0 1 2 ... 8 9.
+			    (nth (mod (1- eff) 10) efforts)))))
+      (org-agenda-filter-apply org-agenda-effort-filter 'effort)))
+   (t (org-agenda-filter-show-all-effort)
+      (message "Effort filter removed"))))
 
 (defun org-agenda-filter-remove-all ()
   "Remove all filters from the current agenda buffer."