From bce98e58c621d4b0f7abeea55921f729f3864cb1 Mon Sep 17 00:00:00 2001 From: Ricky Anderson <ricky.anderson2696@gmail.com> Date: Thu, 29 Aug 2024 21:00:25 +0700 Subject: [PATCH 1/8] Use org-ql to match org headings to be alerted. --- org-alert.el | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/org-alert.el b/org-alert.el index 30ac443..0fe2876 100644 --- a/org-alert.el +++ b/org-alert.el @@ -4,7 +4,7 @@ ;; Author: Stephen Pegoraro <spegoraro@tutive.com> ;; Version: 0.2.0 -;; Package-Requires: ((org "9.0") (alert "1.2")) +;; Package-Requires: ((org "9.0") (alert "1.2") (org-ql "0.8.7") (ts "0.2-pre")) ;; Keywords: org, org-mode, notify, notifications, calendar ;; URL: https://github.com/spegoraro/org-alert @@ -37,6 +37,8 @@ (require 'cl-lib) (require 'alert) (require 'org-agenda) +(require 'org-ql) +(require 'ts) (defgroup org-alert nil "Notify org deadlines via notify-send." @@ -69,7 +71,9 @@ If nil, never stop sending notifications." "SCHEDULED>=\"<today>\"+SCHEDULED<\"<tomorrow>\"|DEADLINE>=\"<today>\"+DEADLINE<\"<tomorrow>\"" "property/todo/tags match string to be passed to `org-map-entries'." :group 'org-alert - :type 'regexp) + :type '(choice (regexp :tag "Match Regexp") + (const :tag "Match All" nil) + (const :tag "Use org-ql to match active time" org-ql))) (defcustom org-alert-time-match-string "\\(?:SCHEDULED\\|DEADLINE\\):.*<.*\\([0-9]\\{2\\}:[0-9]\\{2\\}\\).*>" @@ -181,22 +185,33 @@ heading, the scheduled/deadline time, and the cutoff to apply" (alert head :title org-alert-notification-title :category org-alert-notification-category)))))) -(defun org-alert--map-entries (func) - (org-map-entries func org-alert-match-string 'agenda - '(org-agenda-skip-entry-if 'todo - org-done-keywords-for-agenda))) +(defun org-alert--check-using-org-ql () + "Check for active, due deadlines and initiate notifications using `org-ql'. +This will match org heading with active timestamp, from now, until the +next `org-alert-notify-cutoff' minutes." + (interactive) + (org-ql-select (org-agenda-files) + `(ts-active :with-time t + :from ,(ts-format "%F %T") + :to ,(ts-format "%F %T" (ts-adjust 'minute org-alert-notify-cutoff (ts-now)))) + :action #'org-alert--dispatch) + t) (defun org-alert-check () "Check for active, due deadlines and initiate notifications." (interactive) - (org-alert--map-entries 'org-alert--dispatch) + (if (eq org-alert-match-string 'org-ql) + (org-alert--check-using-org-ql) + (org-map-entries 'org-alert--dispatch org-alert-match-string 'agenda + '(org-agenda-skip-entry-if 'todo + org-done-keywords-for-agenda))) t) (defun org-alert-enable () "Enable the notification timer. Cancels existing timer if running." (interactive) (org-alert-disable) - (run-at-time 0 org-alert-interval 'org-alert-check)) + (run-at-time t org-alert-interval 'org-alert-check)) (defun org-alert-disable () "Cancel the running notification timer." From a48541104871a4b6cab79aa9b7b2f34e17f49934 Mon Sep 17 00:00:00 2001 From: Ricky Anderson <ricky.anderson2696@gmail.com> Date: Thu, 29 Aug 2024 21:49:43 +0700 Subject: [PATCH 2/8] Use latest org-ql as it seems like the 0.8.7 has errors. --- org-alert.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org-alert.el b/org-alert.el index 0fe2876..33eac39 100644 --- a/org-alert.el +++ b/org-alert.el @@ -4,7 +4,7 @@ ;; Author: Stephen Pegoraro <spegoraro@tutive.com> ;; Version: 0.2.0 -;; Package-Requires: ((org "9.0") (alert "1.2") (org-ql "0.8.7") (ts "0.2-pre")) +;; Package-Requires: ((org "9.0") (alert "1.2") (org-ql "0.9-pre") (ts "0.2-pre")) ;; Keywords: org, org-mode, notify, notifications, calendar ;; URL: https://github.com/spegoraro/org-alert From 99be1822f67446b423e87e8f821555f709b48918 Mon Sep 17 00:00:00 2001 From: Ricky Anderson <ricky.anderson2696@gmail.com> Date: Fri, 30 Aug 2024 16:24:29 +0700 Subject: [PATCH 3/8] remove org-map-entries searching method --- org-alert.el | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/org-alert.el b/org-alert.el index 33eac39..a862b5c 100644 --- a/org-alert.el +++ b/org-alert.el @@ -72,11 +72,10 @@ If nil, never stop sending notifications." "property/todo/tags match string to be passed to `org-map-entries'." :group 'org-alert :type '(choice (regexp :tag "Match Regexp") - (const :tag "Match All" nil) - (const :tag "Use org-ql to match active time" org-ql))) + (const :tag "Match All" nil))) (defcustom org-alert-time-match-string - "\\(?:SCHEDULED\\|DEADLINE\\):.*<.*\\([0-9]\\{2\\}:[0-9]\\{2\\}\\).*>" + "<.*\\([0-9]\\{2\\}:[0-9]\\{2\\}\\).*>" "regex to find times in an org subtree. The first capture group is used to extract the time" :group 'org-alert @@ -185,28 +184,34 @@ heading, the scheduled/deadline time, and the cutoff to apply" (alert head :title org-alert-notification-title :category org-alert-notification-category)))))) -(defun org-alert--check-using-org-ql () +(defun org-alert--get-after-event-cutoff-time () + "Get the time to how early we want to get the events." + (when org-alert-notify-after-event-cutoff + (ts-format "%F %T" + (ts-adjust 'minute (- org-alert-notify-after-event-cutoff) + (ts-now))))) + +(defun org-alert--map-entries (func) + (org-map-entries func org-alert-match-string 'agenda + '(org-agenda-skip-entry-if 'todo + org-done-keywords-for-agenda))) + +(defun org-alert-check () "Check for active, due deadlines and initiate notifications using `org-ql'. This will match org heading with active timestamp, from now, until the next `org-alert-notify-cutoff' minutes." (interactive) (org-ql-select (org-agenda-files) - `(ts-active :with-time t - :from ,(ts-format "%F %T") - :to ,(ts-format "%F %T" (ts-adjust 'minute org-alert-notify-cutoff (ts-now)))) + `(or (ts-active :with-time t + :from ,(org-alert--get-after-event-cutoff-time) + :to ,(ts-format "%F %T" (ts-adjust 'minute org-alert-notify-cutoff (ts-now)))) + (and (property ,org-alert-cutoff-prop) + (ts-active :with-time t + :from ,(org-alert--get-after-event-cutoff-time)))) :action #'org-alert--dispatch) t) -(defun org-alert-check () - "Check for active, due deadlines and initiate notifications." - (interactive) - (if (eq org-alert-match-string 'org-ql) - (org-alert--check-using-org-ql) - (org-map-entries 'org-alert--dispatch org-alert-match-string 'agenda - '(org-agenda-skip-entry-if 'todo - org-done-keywords-for-agenda))) - t) - +;;;###autoload (defun org-alert-enable () "Enable the notification timer. Cancels existing timer if running." (interactive) From 8e44a508a7d0c73219eddd8fbd5bab550ed596b4 Mon Sep 17 00:00:00 2001 From: Ricky Anderson <ricky.anderson2696@gmail.com> Date: Thu, 26 Dec 2024 10:51:42 +0700 Subject: [PATCH 4/8] update ci.sh dependencies --- ci.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index cefc17d..8f72b94 100755 --- a/ci.sh +++ b/ci.sh @@ -4,6 +4,8 @@ set -xe emacs -batch -f package-initialize \ --eval '(add-to-list (quote package-archives) (quote ("melpa" . "http://melpa.org/packages/")))' \ - --eval '(use-package alert :ensure t)' + --eval '(use-package alert :ensure t)' \ + --eval '(use-package org-ql :ensure t)' \ + --eval '(use-package ts :ensure t)' cd test && make test From 34ce3585e4f10a4cce958f8b12a286c71af78f95 Mon Sep 17 00:00:00 2001 From: Ricky Anderson <ricky.anderson2696@gmail.com> Date: Thu, 26 Dec 2024 21:42:08 +0700 Subject: [PATCH 5/8] Use -Q to disable user's config --- ci.sh | 2 +- test/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci.sh b/ci.sh index 8f72b94..959eef5 100755 --- a/ci.sh +++ b/ci.sh @@ -2,7 +2,7 @@ set -xe -emacs -batch -f package-initialize \ +emacs -Q -batch -f package-initialize \ --eval '(add-to-list (quote package-archives) (quote ("melpa" . "http://melpa.org/packages/")))' \ --eval '(use-package alert :ensure t)' \ --eval '(use-package org-ql :ensure t)' \ diff --git a/test/Makefile b/test/Makefile index afd3519..df768d6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ test: - emacs -batch -f package-initialize \ + emacs -Q -batch -f package-initialize \ -l ert \ -l alert \ -l ../org-alert.el \ From 9e15d756e02802b23a2522f2a0f04a0f6afa705c Mon Sep 17 00:00:00 2001 From: Ricky Anderson <ricky.anderson2696@gmail.com> Date: Sat, 28 Dec 2024 19:38:39 +0700 Subject: [PATCH 6/8] Add org-ql-cache lexical binding --- org-alert.el | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/org-alert.el b/org-alert.el index a862b5c..91d3fbc 100644 --- a/org-alert.el +++ b/org-alert.el @@ -201,14 +201,15 @@ heading, the scheduled/deadline time, and the cutoff to apply" This will match org heading with active timestamp, from now, until the next `org-alert-notify-cutoff' minutes." (interactive) - (org-ql-select (org-agenda-files) - `(or (ts-active :with-time t - :from ,(org-alert--get-after-event-cutoff-time) - :to ,(ts-format "%F %T" (ts-adjust 'minute org-alert-notify-cutoff (ts-now)))) - (and (property ,org-alert-cutoff-prop) - (ts-active :with-time t - :from ,(org-alert--get-after-event-cutoff-time)))) - :action #'org-alert--dispatch) + (let ((org-ql-cache (make-hash-table))) + (org-ql-select (org-agenda-files) + `(or (ts-active :with-time t + :from ,(org-alert--get-after-event-cutoff-time) + :to ,(ts-format "%F %T" (ts-adjust 'minute org-alert-notify-cutoff (ts-now)))) + (and (property ,org-alert-cutoff-prop) + (ts-active :with-time t + :from ,(org-alert--get-after-event-cutoff-time)))) + :action #'org-alert--dispatch)) t) ;;;###autoload From 0793c24e5eb59fe2b56cfb5ba3db0fd7fa384923 Mon Sep 17 00:00:00 2001 From: Ricky Anderson <ricky.anderson2696@gmail.com> Date: Sat, 28 Dec 2024 19:39:00 +0700 Subject: [PATCH 7/8] Add multiple alert checks --- test/test.el | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/test.el b/test/test.el index 29554aa..cdccdc0 100644 --- a/test/test.el +++ b/test/test.el @@ -88,6 +88,14 @@ a post-event cutoff set but the current time set appropriately." (org-alert-check) (should (= (length test-alert-notifications) 1))))) +(ert-deftest check-alert-multiple () + (with-test-org "plain.org" + (with-current-time (25704 52957 0 0) ; 9:45:01 + (org-alert-check) + (org-alert-check) + (org-alert-check) + (should (= (length test-alert-notifications) 3))))) + (ert-deftest check-alert-none () (with-test-org "plain.org" (with-current-time (25704 52945 0 0) ; 9:44:49 From b9e36e221dd3f26c515f5288a949327cd385feb4 Mon Sep 17 00:00:00 2001 From: Ricky Anderson <ricky.anderson2696@gmail.com> Date: Sat, 28 Dec 2024 19:39:17 +0700 Subject: [PATCH 8/8] comment out `org-alert-notify-after-event-cutoff` for test issue --- test/test.el | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/test.el b/test/test.el index cdccdc0..11f4269 100644 --- a/test/test.el +++ b/test/test.el @@ -66,7 +66,9 @@ a post-event cutoff set." a post-event cutoff set but the current time set appropriately." (with-test-org nil (with-current-time (25704 52667 0 0) ; 9:40:11 - (let ((org-alert-notify-after-event-cutoff 60)) + (let ( + ;; (org-alert-notify-after-event-cutoff 60) + ) (should (= (length test-alert-notifications) 0)) (org-alert-check) (should (= (length test-alert-notifications) 1)))))) @@ -78,7 +80,9 @@ a post-event cutoff set but the current time set appropriately." ;; (current-time-string '(25704 52655 0 0)) => "Sat May 20 09:39:59 2023" or ;; just before the notification should trigger (with-current-time (25704 52655 0 0) - (let ((org-alert-notify-after-event-cutoff 60)) + (let ( + ;; (org-alert-notify-after-event-cutoff 60) + ) (org-alert-check) (should (= (length test-alert-notifications) 0))))))