emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Stefan Kangas <stefan@marxist.se>
To: emacs-orgmode@gnu.org
Subject: [PATCH] New function org-agenda-filter-set
Date: Wed, 20 May 2020 23:23:55 -0700	[thread overview]
Message-ID: <CADwFkmkDvCAt+Awn9GGadCr5u+YH0mXXJknXn3UT1-AZ+wVm+g@mail.gmail.com> (raw)

[-- 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


             reply	other threads:[~2020-05-21  6:24 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-21  6:23 Stefan Kangas [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CADwFkmkDvCAt+Awn9GGadCr5u+YH0mXXJknXn3UT1-AZ+wVm+g@mail.gmail.com \
    --to=stefan@marxist.se \
    --cc=emacs-orgmode@gnu.org \
    --subject='Re: [PATCH] New function org-agenda-filter-set' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Code repositories for project(s) associated with this 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).