* [PATCH] New function org-agenda-filter-set
@ 2020-05-21 6:23 Stefan Kangas
2020-05-23 5:02 ` Kyle Meyer
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Stefan Kangas @ 2020-05-21 6:23 UTC (permalink / raw)
To: emacs-orgmode
[-- Attachment #1: Type: text/plain, Size: 392 bytes --]
Hi all,
Please find attached a patch to add a new function org-agenda-filter-set
which allows you to specify the same strings as in the org-agenda-filter
prompt directly from Lisp. It allows you to do things like:
(org-agenda-filter-set "-@foo-bar")
Before, this would have involved doing more of the heavy lifting
manually using org-agenda-filter-apply.
Best regards,
Stefan Kangas
[-- Attachment #2: 0001-New-function-org-agenda-filter-set.patch --]
[-- Type: text/x-diff, Size: 6020 bytes --]
From 83e67c647d4bfd3e30f8e6e96e77a4192e10f898 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <stefankangas@gmail.com>
Date: Thu, 21 May 2020 07:24:49 +0200
Subject: [PATCH] New function org-agenda-filter-set
* lisp/org-agenda.el (org-agenda-filter)
(org-agenda-filter-set): Refactor out from 'org-agenda-filter', to
create a better interface to filter the agenda from Lisp.
---
lisp/org-agenda.el | 100 +++++++++++++++++++++++++--------------------
1 file changed, 55 insertions(+), 45 deletions(-)
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 8ed5e402d..2362fc542 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -7654,7 +7654,58 @@ consistency with the other filter commands."
(if keep current nil)))
(org-agenda-filter-apply org-agenda-effort-filter 'effort)))))
-(defun org-agenda-filter (&optional strip-or-accumulate)
+(defun org-agenda-filter-set (str &optional force-keep negate)
+ "Set agenda filter from string.
+The string is parsed according to the rules described in
+the `org-agenda-filter' command.
+
+If FORCE-KEEP is non-nil, add the new filter elements to the
+existing ones."
+ (let* ((tag-list (org-agenda-get-represented-tags))
+ (category-list (org-agenda-get-represented-categories))
+ (keep (or force-keep
+ (if (string-match "^\\+[+-]" str)
+ (progn (setq str (substring str 1)) t))))
+ (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))
+ pm s)
+ (while (string-match "^[ \t]*\\([-+]\\)?\\(\\([^-+<>=/ \t]+\\)\\|\\([<>=][0-9:]+\\)\\|\\(/\\([^/]+\\)/?\\)\\)" str)
+ (setq pm (if (match-beginning 1) (match-string 1 str) "+"))
+ (when negate
+ (setq pm (if (equal pm "+") "-" "+")))
+ (cond
+ ((match-beginning 3)
+ ;; category or tag
+ (setq s (match-string 3 str))
+ (cond
+ ((member s tag-list)
+ (add-to-list 'ft (concat pm s) 'append 'equal))
+ ((member s category-list)
+ (add-to-list 'fc (concat pm s) 'append 'equal))
+ (t (message
+ "`%s%s' filter ignored because tag/category is not represented"
+ pm s))))
+ ((match-beginning 4)
+ ;; effort
+ (add-to-list 'fe (concat pm (match-string 4 str)) t 'equal))
+ ((match-beginning 5)
+ ;; regexp
+ (add-to-list 'fr (concat pm (match-string 6 str)) t 'equal)))
+ (setq str (substring str (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 'expand))
+ (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))
+ (run-hooks 'org-agenda-filter-hook)))
+
+(defun org-agenda-filter (&optional strip-or-accumulate filter-string)
"Prompt for a general filter string and apply it to the agenda.
The string may contain filter elements like
@@ -7701,9 +7752,7 @@ the variable `org-agenda-auto-exclude-function'."
(unless (null org-agenda-tag-filter)
(org-agenda-filter-apply org-agenda-tag-filter 'tag 'expand)))
;; Prompt for a filter and act
- (let* ((tag-list (org-agenda-get-represented-tags))
- (category-list (org-agenda-get-represented-categories))
- (negate (equal strip-or-accumulate '(4)))
+ (let* ((negate (equal strip-or-accumulate '(4)))
(cf (mapconcat #'identity org-agenda-category-filter ""))
(tf (mapconcat #'identity org-agenda-tag-filter ""))
(rpl-fn (lambda (c) (replace-regexp-in-string "^\+" "" (or (car c) ""))))
@@ -7716,47 +7765,8 @@ the variable `org-agenda-auto-exclude-function'."
" [+cat-tag<0:10-/regexp/]: ")
'org-agenda-filter-completion-function
nil nil ff))
- (keep (or (if (string-match "^\\+[+-]" f-string)
- (progn (setq f-string (substring f-string 1)) t))
- (equal strip-or-accumulate '(16))))
- (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))
- pm s)
- (while (string-match "^[ \t]*\\([-+]\\)?\\(\\([^-+<>=/ \t]+\\)\\|\\([<>=][0-9:]+\\)\\|\\(/\\([^/]+\\)/?\\)\\)" f-string)
- (setq pm (if (match-beginning 1) (match-string 1 f-string) "+"))
- (when negate
- (setq pm (if (equal pm "+") "-" "+")))
- (cond
- ((match-beginning 3)
- ;; category or tag
- (setq s (match-string 3 f-string))
- (cond
- ((member s tag-list)
- (add-to-list 'ft (concat pm s) 'append 'equal))
- ((member s category-list)
- (add-to-list 'fc (concat pm s) 'append 'equal))
- (t (message
- "`%s%s' filter ignored because tag/category is not represented"
- pm s))))
- ((match-beginning 4)
- ;; effort
- (add-to-list 'fe (concat pm (match-string 4 f-string)) t 'equal))
- ((match-beginning 5)
- ;; regexp
- (add-to-list 'fr (concat pm (match-string 6 f-string)) t 'equal)))
- (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 'expand))
- (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))
- (run-hooks 'org-agenda-filter-hook))))
+ (keep (equal strip-or-accumulate '(16))))
+ (org-agenda-filter-set f-string keep negate))))
(defun org-agenda-filter-completion-function (string _predicate &optional flag)
"Complete a complex filter string.
--
2.26.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] New function org-agenda-filter-set
2020-05-21 6:23 [PATCH] New function org-agenda-filter-set Stefan Kangas
@ 2020-05-23 5:02 ` Kyle Meyer
2020-05-23 5:16 ` Stefan Kangas
2020-05-23 9:07 ` Bastien
2020-06-01 12:50 ` Bastien
2 siblings, 1 reply; 7+ messages in thread
From: Kyle Meyer @ 2020-05-23 5:02 UTC (permalink / raw)
To: Stefan Kangas; +Cc: emacs-orgmode
Stefan Kangas writes:
> Please find attached a patch to add a new function org-agenda-filter-set
> which allows you to specify the same strings as in the org-agenda-filter
> prompt directly from Lisp. It allows you to do things like:
>
> (org-agenda-filter-set "-@foo-bar")
>
> Before, this would have involved doing more of the heavy lifting
> manually using org-agenda-filter-apply.
Sounds good to me.
> Subject: [PATCH] New function org-agenda-filter-set
>
> * lisp/org-agenda.el (org-agenda-filter)
> (org-agenda-filter-set): Refactor out from 'org-agenda-filter', to
> create a better interface to filter the agenda from Lisp.
> ---
> lisp/org-agenda.el | 100 +++++++++++++++++++++++++--------------------
> 1 file changed, 55 insertions(+), 45 deletions(-)
As expected from the description, the bulk of this is code movement, all
of which looked sensible when I inspected it with
--color-moved=default --color-moved-ws=allow-indentation-change
> -(defun org-agenda-filter (&optional strip-or-accumulate)
> +(defun org-agenda-filter-set (str &optional force-keep negate)
> + "Set agenda filter from string.
> +The string is parsed according to the rules described in
> +the `org-agenda-filter' command.
> +
> +If FORCE-KEEP is non-nil, add the new filter elements to the
> +existing ones."
nitpick: Could you update the docstring to explicitly mention STR and to
describe NEGATE?
Thanks for the patch.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] New function org-agenda-filter-set
2020-05-23 5:02 ` Kyle Meyer
@ 2020-05-23 5:16 ` Stefan Kangas
0 siblings, 0 replies; 7+ messages in thread
From: Stefan Kangas @ 2020-05-23 5:16 UTC (permalink / raw)
To: Kyle Meyer; +Cc: emacs-orgmode
[-- Attachment #1: Type: text/plain, Size: 239 bytes --]
Kyle Meyer <kyle@kyleam.com> writes:
> nitpick: Could you update the docstring to explicitly mention STR and to
> describe NEGATE?
Fixed in the attached patch.
> Thanks for the patch.
Thanks for reviewing.
Best regards,
Stefan Kangas
[-- Attachment #2: 0001-New-function-org-agenda-filter-set.patch --]
[-- Type: text/x-diff, Size: 6056 bytes --]
From 5a9a7d810e174dfad30a6ec657b39cbe83879f94 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <stefankangas@gmail.com>
Date: Sat, 23 May 2020 07:13:29 +0200
Subject: [PATCH] New function org-agenda-filter-set
* lisp/org-agenda.el (org-agenda-filter)
(org-agenda-filter-set): Refactor out from 'org-agenda-filter', to
create a better interface to filter the agenda from Lisp.
---
lisp/org-agenda.el | 102 +++++++++++++++++++++++++--------------------
1 file changed, 57 insertions(+), 45 deletions(-)
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index ab13f926c..858de02c7 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -7655,7 +7655,60 @@ consistency with the other filter commands."
(if keep current nil)))
(org-agenda-filter-apply org-agenda-effort-filter 'effort)))))
-(defun org-agenda-filter (&optional strip-or-accumulate)
+(defun org-agenda-filter-set (str &optional force-keep negate)
+ "Set agenda filter from string STR.
+STR is parsed according to the rules described in
+`org-agenda-filter'.
+
+If FORCE-KEEP is non-nil, add the new filter elements to the
+existing ones.
+
+If NEGATE is non-nil, negate the entire filter."
+ (let* ((tag-list (org-agenda-get-represented-tags))
+ (category-list (org-agenda-get-represented-categories))
+ (keep (or force-keep
+ (if (string-match "^\\+[+-]" str)
+ (progn (setq str (substring str 1)) t))))
+ (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))
+ pm s)
+ (while (string-match "^[ \t]*\\([-+]\\)?\\(\\([^-+<>=/ \t]+\\)\\|\\([<>=][0-9:]+\\)\\|\\(/\\([^/]+\\)/?\\)\\)" str)
+ (setq pm (if (match-beginning 1) (match-string 1 str) "+"))
+ (when negate
+ (setq pm (if (equal pm "+") "-" "+")))
+ (cond
+ ((match-beginning 3)
+ ;; category or tag
+ (setq s (match-string 3 str))
+ (cond
+ ((member s tag-list)
+ (add-to-list 'ft (concat pm s) 'append 'equal))
+ ((member s category-list)
+ (add-to-list 'fc (concat pm s) 'append 'equal))
+ (t (message
+ "`%s%s' filter ignored because tag/category is not represented"
+ pm s))))
+ ((match-beginning 4)
+ ;; effort
+ (add-to-list 'fe (concat pm (match-string 4 str)) t 'equal))
+ ((match-beginning 5)
+ ;; regexp
+ (add-to-list 'fr (concat pm (match-string 6 str)) t 'equal)))
+ (setq str (substring str (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 'expand))
+ (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))
+ (run-hooks 'org-agenda-filter-hook)))
+
+(defun org-agenda-filter (&optional strip-or-accumulate filter-string)
"Prompt for a general filter string and apply it to the agenda.
The string may contain filter elements like
@@ -7702,9 +7755,7 @@ the variable `org-agenda-auto-exclude-function'."
(unless (null org-agenda-tag-filter)
(org-agenda-filter-apply org-agenda-tag-filter 'tag 'expand)))
;; Prompt for a filter and act
- (let* ((tag-list (org-agenda-get-represented-tags))
- (category-list (org-agenda-get-represented-categories))
- (negate (equal strip-or-accumulate '(4)))
+ (let* ((negate (equal strip-or-accumulate '(4)))
(cf (mapconcat #'identity org-agenda-category-filter ""))
(tf (mapconcat #'identity org-agenda-tag-filter ""))
(rpl-fn (lambda (c) (replace-regexp-in-string "^\+" "" (or (car c) ""))))
@@ -7717,47 +7768,8 @@ the variable `org-agenda-auto-exclude-function'."
" [+cat-tag<0:10-/regexp/]: ")
'org-agenda-filter-completion-function
nil nil ff))
- (keep (or (if (string-match "^\\+[+-]" f-string)
- (progn (setq f-string (substring f-string 1)) t))
- (equal strip-or-accumulate '(16))))
- (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))
- pm s)
- (while (string-match "^[ \t]*\\([-+]\\)?\\(\\([^-+<>=/ \t]+\\)\\|\\([<>=][0-9:]+\\)\\|\\(/\\([^/]+\\)/?\\)\\)" f-string)
- (setq pm (if (match-beginning 1) (match-string 1 f-string) "+"))
- (when negate
- (setq pm (if (equal pm "+") "-" "+")))
- (cond
- ((match-beginning 3)
- ;; category or tag
- (setq s (match-string 3 f-string))
- (cond
- ((member s tag-list)
- (add-to-list 'ft (concat pm s) 'append 'equal))
- ((member s category-list)
- (add-to-list 'fc (concat pm s) 'append 'equal))
- (t (message
- "`%s%s' filter ignored because tag/category is not represented"
- pm s))))
- ((match-beginning 4)
- ;; effort
- (add-to-list 'fe (concat pm (match-string 4 f-string)) t 'equal))
- ((match-beginning 5)
- ;; regexp
- (add-to-list 'fr (concat pm (match-string 6 f-string)) t 'equal)))
- (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 'expand))
- (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))
- (run-hooks 'org-agenda-filter-hook))))
+ (keep (equal strip-or-accumulate '(16))))
+ (org-agenda-filter-set f-string keep negate))))
(defun org-agenda-filter-completion-function (string _predicate &optional flag)
"Complete a complex filter string.
--
2.26.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] New function org-agenda-filter-set
2020-05-21 6:23 [PATCH] New function org-agenda-filter-set Stefan Kangas
2020-05-23 5:02 ` Kyle Meyer
@ 2020-05-23 9:07 ` Bastien
2020-06-01 12:50 ` Bastien
2 siblings, 0 replies; 7+ messages in thread
From: Bastien @ 2020-05-23 9:07 UTC (permalink / raw)
To: Stefan Kangas; +Cc: emacs-orgmode
Hi Stefan,
thanks for this refactoring, it is indeed useful.
I applied you patch against current master.
Best,
--
Bastien
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] New function org-agenda-filter-set
2020-05-21 6:23 [PATCH] New function org-agenda-filter-set Stefan Kangas
2020-05-23 5:02 ` Kyle Meyer
2020-05-23 9:07 ` Bastien
@ 2020-06-01 12:50 ` Bastien
2020-06-05 3:58 ` Kyle Meyer
2 siblings, 1 reply; 7+ messages in thread
From: Bastien @ 2020-06-01 12:50 UTC (permalink / raw)
To: Stefan Kangas; +Cc: emacs-orgmode
Hi Stefan,
Stefan Kangas <stefan@marxist.se> writes:
> Please find attached a patch to add a new function org-agenda-filter-set
> which allows you to specify the same strings as in the org-agenda-filter
> prompt directly from Lisp. It allows you to do things like:
I've seen problems with this new function when completing in agendas:
hitting '/' does not see what tags are available for completion in the
current buffer.
I'm reverting e9b1b8fde5 from master for now. If you see what's wrong,
please resubmit a patch.
Thanks!
--
Bastien
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] New function org-agenda-filter-set
2020-06-01 12:50 ` Bastien
@ 2020-06-05 3:58 ` Kyle Meyer
2020-09-05 7:45 ` Bastien
0 siblings, 1 reply; 7+ messages in thread
From: Kyle Meyer @ 2020-06-05 3:58 UTC (permalink / raw)
To: Bastien, Stefan Kangas; +Cc: emacs-orgmode
Bastien writes:
> I've seen problems with this new function when completing in agendas:
> hitting '/' does not see what tags are available for completion in the
> current buffer.
>
> I'm reverting e9b1b8fde5 from master for now. If you see what's wrong,
> please resubmit a patch.
Stepping through both versions, it looks like the crucial thing is that
org-agenda-get-represented-tags needs to be called _before_ the
completion function. If it's not, org-agenda-filter-completion-function
calls -get-represented-tags with an unset cache, and it returns nil
because the (derived-mode-p 'org-agenda-mode) condition is nil.
The same goes for org-agenda-get-represented-categories.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] New function org-agenda-filter-set
2020-06-05 3:58 ` Kyle Meyer
@ 2020-09-05 7:45 ` Bastien
0 siblings, 0 replies; 7+ messages in thread
From: Bastien @ 2020-09-05 7:45 UTC (permalink / raw)
To: Kyle Meyer; +Cc: emacs-orgmode, Stefan Kangas
Hi Kyle and Stefan,
Kyle Meyer <kyle@kyleam.com> writes:
> Bastien writes:
>
>> I've seen problems with this new function when completing in agendas:
>> hitting '/' does not see what tags are available for completion in the
>> current buffer.
>>
>> I'm reverting e9b1b8fde5 from master for now. If you see what's wrong,
>> please resubmit a patch.
>
> Stepping through both versions, it looks like the crucial thing is that
> org-agenda-get-represented-tags needs to be called _before_ the
> completion function. If it's not, org-agenda-filter-completion-function
> calls -get-represented-tags with an unset cache, and it returns nil
> because the (derived-mode-p 'org-agenda-mode) condition is nil.
>
> The same goes for org-agenda-get-represented-categories.
Thanks for analysing this -- Stefan, if you still feel like going
through this refactoring, this would be a welcome improvement for
after 9.4 (coming soon).
--
Bastien
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-09-05 7:46 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-05-21 6:23 [PATCH] New function org-agenda-filter-set Stefan Kangas
2020-05-23 5:02 ` Kyle Meyer
2020-05-23 5:16 ` Stefan Kangas
2020-05-23 9:07 ` Bastien
2020-06-01 12:50 ` Bastien
2020-06-05 3:58 ` Kyle Meyer
2020-09-05 7:45 ` Bastien
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).