Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use org-ql to match org headings to be alerted. #41

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

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 alert :ensure t)' \
--eval '(use-package org-ql :ensure t)' \
--eval '(use-package ts :ensure t)'

cd test && make test
33 changes: 27 additions & 6 deletions org-alert.el
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

;; Author: Stephen Pegoraro <[email protected]>
;; Version: 0.2.0
;; Package-Requires: ((org "9.0") (alert "1.2"))
;; 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

Expand Down Expand Up @@ -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."
Expand Down Expand Up @@ -69,10 +71,11 @@ 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)))

(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
Expand Down Expand Up @@ -181,22 +184,40 @@ 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--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."
"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-alert--map-entries '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
(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."
Expand Down
2 changes: 1 addition & 1 deletion test/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
test:
emacs -batch -f package-initialize \
emacs -Q -batch -f package-initialize \
-l ert \
-l alert \
-l ../org-alert.el \
Expand Down
16 changes: 14 additions & 2 deletions test/test.el
Original file line number Diff line number Diff line change
Expand Up @@ -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))))))
Expand All @@ -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))))))

Expand All @@ -88,6 +92,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
Expand Down
Loading