From 7893737406064b39832facdbe532f221cfda1d5e Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Wed, 21 Aug 2019 14:21:55 +0200 Subject: [PATCH 1/9] Add the filter commands to the agenda menu * lisp/org-agenda.el (easy-menu-define): Add filter commands. --- lisp/org-agenda.el | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index e4a334dbd..a57d44fe3 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -2482,8 +2482,18 @@ The following commands are available: :keys "v A"] "--" ["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict]) - ["Write view to file" org-agenda-write t] + ("Filter current view" + ["by category at cursor" org-agenda-filter-by-category t] + ["by tag" org-agenda-filter-by-tag t] + ["by effort" org-agenda-filter-by-effort t] + ["by regexp" org-agenda-filter-by-regexp t] + ["by top-level headline" org-agenda-filter-by-top-headline t] + "--" + ["Remove all filtering" org-agenda-filter-remove-all t] + "--" + ["limit" org-agenda-limit-interactively t]) ["Rebuild buffer" org-agenda-redo t] + ["Write view to file" org-agenda-write t] ["Save all Org buffers" org-save-all-org-buffers t] "--" ["Show original entry" org-agenda-show t] From 8dfe826a0bb144182fe99b49548788f2469921f7 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Wed, 21 Aug 2019 14:57:15 +0200 Subject: [PATCH 2/9] Agenda category filter now offers completion for categories * lisp/org-agenda.el (org-agenda-all-categories): New function. (org-agenda-filter-by-category): Implement completion on categories. --- lisp/org-agenda.el | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index a57d44fe3..0b7958116 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -7439,17 +7439,30 @@ With a prefix argument, do so in all agenda buffers." "Return the category of the agenda line." (org-get-at-bol 'org-category)) +(defun org-agenda-all-categories () + "Return a list of all categories used in this agenda buffer." + (let ((pos (point-min)) categories) + (while (and (< pos (point-max)) + (setq pos (next-single-property-change + pos 'org-category nil (point-max)))) + (push (get-text-property pos 'org-category) categories)) + (nreverse (org-uniquify (delq nil categories))))) + (defun org-agenda-filter-by-category (strip) "Filter lines in the agenda buffer that have a specific category. The category is that of the current line. -Without prefix argument, keep only the lines of that category. -With a prefix argument, exclude the lines of that category. -" +Without prefix argument STRIP, keep only the lines of that category. +With a prefix argument, exclude the lines of that category." (interactive "P") (if (and org-agenda-filtered-by-category org-agenda-category-filter) (org-agenda-filter-show-all-cat) - (let ((cat (org-no-properties (org-agenda-get-category)))) + (let* ((categories (org-agenda-all-categories)) + (defcat (org-no-properties (or (org-agenda-get-category) + (car categories)))) + (cat (completing-read (format "Category [%s]: " defcat) + (org-agenda-all-categories) + nil t nil nil defcat))) (cond ((and cat strip) (org-agenda-filter-apply From 8c011126b5d79c554f3f42de104e2f46af36b697 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Tue, 27 Aug 2019 09:01:58 +0200 Subject: [PATCH 3/9] Make pressing `_' twice in agenda remove the effort filter * lisp/org-agenda.el (org-agenda-filter-by-effort): Pressing `_' again will remove the effort filter. This aligns the command with the tags filter. --- lisp/org-agenda.el | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 0b7958116..977260d44 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -7537,27 +7537,31 @@ With two prefix arguments, remove the effort filters." (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 <)"))) + (while (not (memq op '(?< ?> ?= ?_))) + (setq op (read-char-exclusive "Effort operator? (> = or <) or press `_' again to remove filter"))) ;; 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))) + (if (eq op ?_) + (progn + (org-agenda-filter-show-all-effort) + (message "Effort filter removed")) + (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")))) From fa792e92319a76428856d3ab588031085f56ed57 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Tue, 27 Aug 2019 09:15:53 +0200 Subject: [PATCH 4/9] Show a message when category filter has been removed * lisp/org-agenda.el (org-agenda-filter-by-category): Show a message when filter has been removed. --- lisp/org-agenda.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 977260d44..6582049d4 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -7456,7 +7456,9 @@ With a prefix argument, exclude the lines of that category." (interactive "P") (if (and org-agenda-filtered-by-category org-agenda-category-filter) - (org-agenda-filter-show-all-cat) + (progn + (org-agenda-filter-show-all-cat) + (message "All categories are shown")) (let* ((categories (org-agenda-all-categories)) (defcat (org-no-properties (or (org-agenda-get-category) (car categories)))) From 36dc6ae644d54ad9cdbbdd4c88fcf9f3738c2ae2 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Wed, 28 Aug 2019 08:37:07 +0200 Subject: [PATCH 5/9] Lay the groundwork for new filter interface * lisp/org-agenda.el (org-agenda-get-represented-categories): New function. (org-agenda-get-represented-tags): Added a caching mechanism. * (org-agenda-all-categories): Removed again, deferring to `org-agenda-get-represented-categories'. * lisp/org-agenda.el (org-agenda-represented-categories) (org-agenda-represented-tags): New variables. (org-agenda-finalize): Remove the caches for represented tags and categories. --- lisp/org-agenda.el | 51 +++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 6582049d4..1c4f05714 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -3636,6 +3636,10 @@ removed from the entry content. Currently only `planning' is allowed here." (defvar org-agenda-regexp-filter nil) (defvar org-agenda-effort-filter nil) (defvar org-agenda-top-headline-filter nil) +(defvar org-agenda-represented-categories nil + "Cache for the list of all categories in the agenda.") +(defvar org-agenda-represented-tags nil + "Cache for the list of all categories in the agenda.") (defvar org-agenda-tag-filter-preset nil "A preset of the tags filter used for secondary agenda filtering. This must be a list of strings, each string must be a single tag preceded @@ -3844,6 +3848,8 @@ FILTER-ALIST is an alist of filters we need to apply when (org-with-point-at mrk (mapcar #'downcase (org-get-tags))))))))) (run-hooks 'org-agenda-finalize-hook) + (setq org-agenda-represented-tags nil + org-agenda-represented-categories nil) (when org-agenda-top-headline-filter (org-agenda-filter-top-headline-apply org-agenda-top-headline-filter)) @@ -7439,15 +7445,7 @@ With a prefix argument, do so in all agenda buffers." "Return the category of the agenda line." (org-get-at-bol 'org-category)) -(defun org-agenda-all-categories () - "Return a list of all categories used in this agenda buffer." - (let ((pos (point-min)) categories) - (while (and (< pos (point-max)) - (setq pos (next-single-property-change - pos 'org-category nil (point-max)))) - (push (get-text-property pos 'org-category) categories)) - (nreverse (org-uniquify (delq nil categories))))) - + (defun org-agenda-filter-by-category (strip) "Filter lines in the agenda buffer that have a specific category. The category is that of the current line. @@ -7666,17 +7664,32 @@ also press `-' or `+' to switch between filtering and excluding." (org-agenda-filter-apply org-agenda-tag-filter 'tag expand)) (t (error "Invalid tag selection character %c" char))))) -(defun org-agenda-get-represented-tags () - "Get a list of all tags currently represented in the agenda." - (let (p tags) - (save-excursion - (goto-char (point-min)) - (while (setq p (next-single-property-change (point) 'tags)) - (goto-char p) - (mapc (lambda (x) (add-to-list 'tags x)) - (get-text-property (point) 'tags)))) - tags)) +(defun org-agenda-get-represented-categories () + "Return a list of all categories used in this agenda buffer." + (or org-agenda-represented-categories + (when (derived-mode-p 'org-agenda-mode) + (let ((pos (point-min)) categories) + (while (and (< pos (point-max)) + (setq pos (next-single-property-change + pos 'org-category nil (point-max)))) + (push (get-text-property pos 'org-category) categories)) + (setq org-agenda-represented-categories + (nreverse (org-uniquify (delq nil categories)))))))) +(defun org-agenda-get-represented-tags () + "Return a list of all tags used in this agenda buffer. +These will be lower-case, for filtering." + (or org-agenda-represented-tags + (when (derived-mode-p 'org-agenda-mode) + (let ((pos (point-min)) tags-lists tt) + (while (and (< pos (point-max)) + (setq pos (next-single-property-change + pos 'tags nil (point-max)))) + (setq tt (get-text-property pos 'tags)) + (if tt (push tt tags-lists))) + (setq org-agenda-represented-tags + (nreverse (org-uniquify + (delq nil (apply 'append tags-lists))))))))) (defun org-agenda-filter-make-matcher (filter type &optional expand) "Create the form that tests a line for agenda filter. Optional From 6543716d67be4d61ca94f5fc24b6143be4ca7329 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Thu, 29 Aug 2019 07:10:05 +0200 Subject: [PATCH 6/9] Compactify the modeline display of filters * lisp/org-agenda.el (org-agenda-filter-variables): New constant. (org-agenda-filter-any): New function. --- lisp/org-agenda.el | 40 +++++++++++++++++++++++++--------------- lisp/org-faces.el | 8 ++++---- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 1c4f05714..8cdaf2cb1 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -3636,6 +3636,7 @@ removed from the entry content. Currently only `planning' is allowed here." (defvar org-agenda-regexp-filter nil) (defvar org-agenda-effort-filter nil) (defvar org-agenda-top-headline-filter nil) + (defvar org-agenda-represented-categories nil "Cache for the list of all categories in the agenda.") (defvar org-agenda-represented-tags nil @@ -3650,6 +3651,19 @@ the entire agenda view. In a block agenda, it will not work reliably to define a filter for one of the individual blocks. You need to set it in the global options and expect it to be applied to the entire view.") +(defconst org-agenda-filter-variables + '((category . org-agenda-category-filter) + (tag . org-agenda-tag-filter) + (effort . org-agenda-effort-filter) + (regexp . org-agenda-regexp-filter)) + "Alist of filter types and associated variables") +(defun org-agenda-filter-any () + "Is any filter active?" + (eval (cons 'or (mapcar (lambda (x) + (or (symbol-value (cdr x)) + (get :preset-filter x))) + org-agenda-filter-variables)))) + (defvar org-agenda-category-filter-preset nil "A preset of the category filter used for secondary agenda filtering. This must be a list of strings, each string must be a single category @@ -3747,6 +3761,7 @@ FILTER-ALIST is an alist of filters we need to apply when (put 'org-agenda-tag-filter :preset-filter nil) (put 'org-agenda-category-filter :preset-filter nil) (put 'org-agenda-regexp-filter :preset-filter nil) + (put 'org-agenda-effort-filter :preset-filter nil) ;; Popup existing buffer (org-agenda-prepare-window (get-buffer org-agenda-buffer-name) filter-alist) @@ -8392,56 +8407,51 @@ When called with a prefix argument, include all archive files as well." ((eq org-agenda-show-log 'clockcheck) " ClkCk") (org-agenda-show-log " Log") (t "")) + (if (org-agenda-filter-any) " " "") (if (or org-agenda-category-filter (get 'org-agenda-category-filter :preset-filter)) '(:eval (propertize - (concat " <" + (concat "[" (mapconcat 'identity (append (get 'org-agenda-category-filter :preset-filter) org-agenda-category-filter) "") - ">") + "]") 'face 'org-agenda-filter-category 'help-echo "Category used in filtering")) "") (if (or org-agenda-tag-filter (get 'org-agenda-tag-filter :preset-filter)) '(:eval (propertize - (concat " {" - (mapconcat + (concat (mapconcat 'identity (append (get 'org-agenda-tag-filter :preset-filter) org-agenda-tag-filter) - "") - "}") + "")) 'face 'org-agenda-filter-tags 'help-echo "Tags used in filtering")) "") (if (or org-agenda-effort-filter (get 'org-agenda-effort-filter :preset-filter)) '(:eval (propertize - (concat " {" - (mapconcat + (concat (mapconcat 'identity (append (get 'org-agenda-effort-filter :preset-filter) org-agenda-effort-filter) - "") - "}") + "")) 'face 'org-agenda-filter-effort 'help-echo "Effort conditions used in filtering")) "") (if (or org-agenda-regexp-filter (get 'org-agenda-regexp-filter :preset-filter)) '(:eval (propertize - (concat " [" - (mapconcat - 'identity + (concat (mapconcat + (lambda (x) (concat (substring x 0 1) "/" (substring x 1) "/")) (append (get 'org-agenda-regexp-filter :preset-filter) org-agenda-regexp-filter) - "") - "]") + "")) 'face 'org-agenda-filter-regexp 'help-echo "Regexp used in filtering")) "") (if org-agenda-archives-mode diff --git a/lisp/org-faces.el b/lisp/org-faces.el index 8e9726cce..b7925982e 100644 --- a/lisp/org-faces.el +++ b/lisp/org-faces.el @@ -559,10 +559,6 @@ month and 365.24 days for a year)." "Face for tag(s) in the mode-line when filtering the agenda." :group 'org-faces) -(defface org-agenda-filter-regexp '((t :inherit mode-line)) - "Face for regexp(s) in the mode-line when filtering the agenda." - :group 'org-faces) - (defface org-agenda-filter-category '((t :inherit mode-line)) "Face for categories in the mode-line when filtering the agenda." :group 'org-faces) @@ -571,6 +567,10 @@ month and 365.24 days for a year)." "Face for effort in the mode-line when filtering the agenda." :group 'org-faces) +(defface org-agenda-filter-regexp '((t :inherit mode-line)) + "Face for regexp(s) in the mode-line when filtering the agenda." + :group 'org-faces) + (defface org-time-grid ;Copied from `font-lock-variable-name-face' '((((class color) (min-colors 16) (background light)) (:foreground "DarkGoldenrod")) (((class color) (min-colors 16) (background dark)) (:foreground "LightGoldenrod")) From 69bf64419b798d46cec5a3cf5a2ae4af08016109 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Thu, 29 Aug 2019 17:43:24 +0200 Subject: [PATCH 7/9] Add new generic filter interface * lisp/org-agenda.el (org-agenda-filter): New function. (org-agenda-filter-completion-function): New function. --- lisp/org-agenda.el | 113 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 5 deletions(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 8cdaf2cb1..0ffb3dc79 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -2402,6 +2402,7 @@ The following commands are available: (org-defkey org-agenda-mode-map "/" 'org-agenda-filter-by-tag) (org-defkey org-agenda-mode-map "_" 'org-agenda-filter-by-effort) (org-defkey org-agenda-mode-map "=" 'org-agenda-filter-by-regexp) +(org-defkey org-agenda-mode-map "\\" 'org-agenda-filter) (org-defkey org-agenda-mode-map "|" 'org-agenda-filter-remove-all) (org-defkey org-agenda-mode-map "~" 'org-agenda-limit-interactively) (org-defkey org-agenda-mode-map "<" 'org-agenda-filter-by-category) @@ -2483,6 +2484,8 @@ The following commands are available: "--" ["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict]) ("Filter current view" + ["with generic interface" org-agenda-filter t] + "--" ["by category at cursor" org-agenda-filter-by-category t] ["by tag" org-agenda-filter-by-tag t] ["by effort" org-agenda-filter-by-effort t] @@ -3659,11 +3662,12 @@ the global options and expect it to be applied to the entire view.") "Alist of filter types and associated variables") (defun org-agenda-filter-any () "Is any filter active?" - (eval (cons 'or (mapcar (lambda (x) - (or (symbol-value (cdr x)) - (get :preset-filter x))) - org-agenda-filter-variables)))) - + (let ((form (cons 'or (mapcar (lambda (x) + (if (or (symbol-value (cdr x)) + (get :preset-filter x)) + t nil)) + org-agenda-filter-variables)))) + (eval form))) (defvar org-agenda-category-filter-preset nil "A preset of the category filter used for secondary agenda filtering. This must be a list of strings, each string must be a single category @@ -7580,6 +7584,105 @@ With two prefix arguments, remove the effort filters." (t (org-agenda-filter-show-all-effort) (message "Effort filter removed")))) + +(defun org-agenda-filter (&optional keep) + "Prompt for a general filter string and apply it to the agenda. +The new filter replaces all existing elements. When called with a +prefix arg KEEP, add the new elements to the existing filter. + +The string may contain filter elements like + ++category ++tag ++ and = are also allowed as effort operators ++/regexp/ + +Instead of `+', `-' is allowed to strip the agenda of matching entries. +`+' is optional if it is not required to separate two string parts. +Multiple filter elements can be concatenated without spaces, for example + + +work-John<0:10-/plot/ + +selects entries with category `work' and effort estimates below 10 minutes, +and deselects entries with tag `John' or matching the regexp `plot'. + +During entry of the filter, completion for tags, categories and effort +values is offered. Since the syntax for categories and tags is identical +there should be no overlap between categoroes and tags. If there is, tags +get priority." + (interactive "P") + (let* ((tag-list (org-agenda-get-represented-tags)) + (category-list (org-agenda-get-represented-categories)) + (f-string (completing-read "Filter [+cat-tag<0:10-/regexp/]: " 'org-agenda-filter-completion-function)) + (fc (if keep org-agenda-category-filter)) + (ft (if keep org-agenda-tag-filter)) + (fe (if keep org-agenda-effort-filter)) + (fr (if keep org-agenda-regexp-filter))) + (while (string-match "^[ \t]*\\([-+]\\)?\\(\\([^-+<>=/ \t]+\\)\\|\\([<>=][0-9:]+\\)\\|\\(/\\([^/]+\\)/?\\)\\)" + f-string) + (setq log (if (match-beginning 1) (match-string 1 f-string) "+")) + (cond + ((match-beginning 3) + ;; category or tag + (setq s (match-string 3 f-string)) + (cond ((member s tag-list) + (push (concat log s) ft)) + ((member s category-list) + (push (concat log s) fc)) + (t (message "`%s%s' filter ignored because it is not represented as tag or category" log s)))) + ((match-beginning 4) + ;; effort + (push (concat log (match-string 4 f-string)) fe)) + ((match-beginning 5) + ;; regexp + (push (concat log (match-string 6 f-string)) fr))) + (setq f-string (substring f-string (match-end 0)))) + (org-agenda-filter-remove-all) + (and fc (org-agenda-filter-apply + (setq org-agenda-category-filter fc) 'category)) + (and ft (org-agenda-filter-apply + (setq org-agenda-tag-filter ft) 'tag)) + (and fe (org-agenda-filter-apply + (setq org-agenda-effort-filter fe) 'effort)) + (and fr (org-agenda-filter-apply + (setq org-agenda-regexp-filter fr) 'regexp)) + )) + +(defun org-agenda-filter-completion-function (string _predicate &optional flag) + "Complete a complex filter string +FLAG specifies the type of completion operation to perform. This +function is passed as a collection function to `completing-read', +which see." + (let ((completion-ignore-case t) ;tags are case-sensitive + (confirm (lambda (x) (stringp x))) + (prefix "") + (operator "") + table) + (when (string-match "^\\(.*\\([-+<>=]\\)\\)\\([^-+<>=]*\\)$" string) + (setq prefix (match-string 1 string) + operator (match-string 2 string) + string (match-string 3 string))) + (cond + ((member operator '("+" "-" "" nil)) + (setq table (append (org-agenda-get-represented-categories) + (org-agenda-get-represented-tags)))) + ((member operator '("<" ">" "=")) + (setq table (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") + " +"))) + (t (setq table nil))) + (pcase flag + (`t (all-completions string table confirm)) + (`lambda (assoc string table)) ;exact match? + (`nil + (pcase (try-completion string table confirm) + ((and completion (pred stringp)) + (concat prefix completion)) + (completion completion))) + (_ nil)))) + (defun org-agenda-filter-remove-all () "Remove all filters from the current agenda buffer." (interactive) From 26cde0972d5af9977e886da05f50bec8b5b1a5bd Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Thu, 29 Aug 2019 21:33:11 +0200 Subject: [PATCH 8/9] Document the new additional filter interface * doc/org-manual.org (Filtering in the agenda): Document new filter function. --- doc/org-manual.org | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/doc/org-manual.org b/doc/org-manual.org index cfb673c63..c64773e14 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -9109,12 +9109,6 @@ custom agenda commands. option ~org-agenda-category-filter-preset~. See [[*Setting options for custom commands]]. -- {{{kbd(^)}}} (~org-agenda-filter-by-top-headline~) :: - - #+findex: org-agenda-filter-by-top-headline - Filter the current agenda view and only display the siblings and the - parent headline of the one at point. - - {{{kbd(=)}}} (~org-agenda-filter-by-regexp~) :: #+findex: org-agenda-filter-by-regexp @@ -9160,6 +9154,35 @@ custom agenda commands. option ~org-agenda-effort-filter-preset~. See [[*Setting options for custom commands]]. +- {{{kbd(\)}}} (~org-agenda-filter~) :: + + #+findex: org-agenda-filter + This is an alternative interface to all four filter methods + described above. At the prompt, one would specify different filter + elements in a single string, with full completion support. For + example, + + #+begin_example + +work-John<0:10-/plot/ + #+end_example + + selects entries with category `work' and effort estimates below 10 + minutes, and deselects entries with tag `John' or matching the + regexp `plot'. `+' can be left out if that does not lead to + ambiguities. The sequence of elements is arbitrary. The filter + syntax assumes that there is no overlap between categories and tags + (tags will take priority). If you reply to the prompt with the + empty string, all filtering is removed. If a filter is specified, + it replaces all current filters. But if you call the command with a + prefix argument, the new filter elements are added to the active + ones. + +- {{{kbd(^)}}} (~org-agenda-filter-by-top-headline~) :: + + #+findex: org-agenda-filter-by-top-headline + Filter the current agenda view and only display the siblings and the + parent headline of the one at point. + - {{{kbd(|)}}} (~org-agenda-filter-remove-all~) :: Remove all filters in the current agenda view. From 4edf93a6ded5075ab17a8523cae6d3ff2c204f95 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Thu, 29 Aug 2019 22:00:34 +0200 Subject: [PATCH 9/9] Fix compiler warnings in the new filter code --- lisp/org-agenda.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 0ffb3dc79..617c6df81 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -7476,11 +7476,11 @@ With a prefix argument, exclude the lines of that category." (progn (org-agenda-filter-show-all-cat) (message "All categories are shown")) - (let* ((categories (org-agenda-all-categories)) + (let* ((categories (org-agenda-get-represented-categories)) (defcat (org-no-properties (or (org-agenda-get-category) (car categories)))) (cat (completing-read (format "Category [%s]: " defcat) - (org-agenda-all-categories) + (org-agenda-get-represented-categories) nil t nil nil defcat))) (cond ((and cat strip) @@ -7617,7 +7617,8 @@ get priority." (fc (if keep org-agenda-category-filter)) (ft (if keep org-agenda-tag-filter)) (fe (if keep org-agenda-effort-filter)) - (fr (if keep org-agenda-regexp-filter))) + (fr (if keep org-agenda-regexp-filter)) + log s) (while (string-match "^[ \t]*\\([-+]\\)?\\(\\([^-+<>=/ \t]+\\)\\|\\([<>=][0-9:]+\\)\\|\\(/\\([^/]+\\)/?\\)\\)" f-string) (setq log (if (match-beginning 1) (match-string 1 f-string) "+"))