[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/org-notify 1c65ee9597 16/23: org-notify.el: update to v
From: |
ELPA Syncer |
Subject: |
[elpa] externals/org-notify 1c65ee9597 16/23: org-notify.el: update to version in org-mode distribution |
Date: |
Mon, 25 Jul 2022 12:57:57 -0400 (EDT) |
branch: externals/org-notify
commit 1c65ee95977289273b1877173e6950b3190a5157
Author: Peter Münster <pmrb@free.fr>
Commit: Peter Münster <pmrb@free.fr>
org-notify.el: update to version in org-mode distribution
---
org-notify.el | 169 ++++++++++++++++++++++++++++++++++------------------------
1 file changed, 99 insertions(+), 70 deletions(-)
diff --git a/org-notify.el b/org-notify.el
index 9ddf15078d..25e88691c0 100644
--- a/org-notify.el
+++ b/org-notify.el
@@ -1,10 +1,12 @@
;;; org-notify.el --- Notifications for Org-mode
-;; Copyright (C) 2012 Free Software Foundation, Inc.
+;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
;; Author: Peter Münster <pmrb@free.fr>
;; Keywords: notification, todo-list, alarm, reminder, pop-up
+;; This file is not part of GNU Emacs.
+
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
@@ -16,7 +18,7 @@
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
@@ -35,6 +37,7 @@
;; (org-notify-start)
;; Example setup:
+;;
;; (org-notify-add 'appt
;; '(:time "-1s" :period "20s" :duration 10
;; :actions (-message -ding))
@@ -42,18 +45,19 @@
;; :actions -notify)
;; '(:time "2h" :period "5m" :actions -message)
;; '(:time "3d" :actions -email))
+;;
;; This means for todo-items with `notify' property set to `appt': 3 days
;; before deadline, send a reminder-email, 2 hours before deadline, start to
;; send messages every 5 minutes, then 15 minutes before deadline, start to
-;; pop up notification windows every 2 minutes. The timeout of the window is
-;; set to 100 seconds. Finally, when deadline is overdue, send messages and
+;; pop up notification windows every 2 minutes. The timeout of the window is
+;; set to 100 seconds. Finally, when deadline is overdue, send messages and
;; make noise."
;; Take also a look at the function `org-notify-add'.
;;; Code:
-(eval-when-compile (require 'cl))
+(eval-when-compile (require 'cl-lib))
(require 'org-element)
(declare-function appt-delete-window "appt" ())
@@ -70,6 +74,11 @@
:type 'boolean
:group 'org-notify)
+(defcustom org-notify-max-notifications-per-run 3
+ "Maximum number of notifications per run of `org-notify-process'."
+ :type 'integer
+ :group 'org-notify)
+
(defconst org-notify-actions
'("show" "show" "done" "done" "hour" "one hour later" "day" "one day later"
"week" "one week later")
@@ -104,12 +113,21 @@
(cdr (assoc (match-string 3 str) conv))
(if (= (length (match-string 1 str)) 1) -1 1)))))
+(defun org-notify-convert-deadline (orig)
+ "Convert original deadline from `org-element-parse-buffer' to
+simple timestamp string."
+ (if orig
+ (replace-regexp-in-string "^<\\|>$" ""
+ (plist-get (plist-get orig 'timestamp)
+ :raw-value))))
+
(defun org-notify-make-todo (heading &rest ignored)
"Create one todo item."
- (macrolet ((get (k) `(plist-get list ,k))
+ (cl-macrolet ((get (k) `(plist-get list ,k))
(pr (k v) `(setq result (plist-put result ,k ,v))))
- (let* ((list (nth 1 heading)) (notify (or (get :notify) "default"))
- (deadline (get :deadline)) (heading (get :raw-value))
+ (let* ((list (nth 1 heading)) (notify (or (get :NOTIFY) "default"))
+ (deadline (org-notify-convert-deadline (get :deadline)))
+ (heading (get :raw-value))
result)
(when (and (eq (get :todo-type) 'todo) heading deadline)
(pr :heading heading) (pr :notify (intern notify))
@@ -117,82 +135,90 @@
(pr :file (nth org-notify-parse-file (org-agenda-files 'unrestricted)))
(pr :timestamp deadline) (pr :uid (md5 (concat heading deadline)))
(pr :deadline (- (org-time-string-to-seconds deadline)
- (org-float-time))))
+ (float-time))))
result)))
(defun org-notify-todo-list ()
"Create the todo-list for one org-agenda file."
(let* ((files (org-agenda-files 'unrestricted))
(max (1- (length files))))
- (setq org-notify-parse-file
- (if (or (not org-notify-parse-file) (>= org-notify-parse-file max))
- 0
- (1+ org-notify-parse-file)))
- (save-excursion
- (with-current-buffer (find-file-noselect
- (nth org-notify-parse-file files))
- (org-element-map (org-element-parse-buffer 'headline)
- 'headline 'org-notify-make-todo)))))
+ (when files
+ (setq org-notify-parse-file
+ (if (or (not org-notify-parse-file) (>= org-notify-parse-file max))
+ 0
+ (1+ org-notify-parse-file)))
+ (save-excursion
+ (with-current-buffer (find-file-noselect
+ (nth org-notify-parse-file files))
+ (org-element-map (org-element-parse-buffer 'headline)
+ 'headline 'org-notify-make-todo))))))
(defun org-notify-maybe-too-late (diff period heading)
- "Print waring message, when notified significantly later than defined by
+ "Print warning message, when notified significantly later than defined by
PERIOD."
(if (> (/ diff period) 1.5)
(message "Warning: notification for \"%s\" behind schedule!" heading))
t)
-(defun org-notify-process ()
+(cl-defun org-notify-process ()
"Process the todo-list, and possibly notify user about upcoming or
forgotten tasks."
- (macrolet ((prm (k) `(plist-get prms ,k)) (td (k) `(plist-get todo ,k)))
- (dolist (todo (org-notify-todo-list))
- (let* ((deadline (td :deadline)) (heading (td :heading))
- (uid (td :uid)) (last-run-sym
- (intern (concat ":last-run-" uid))))
- (dolist (prms (plist-get org-notify-map (td :notify)))
- (when (< deadline (org-notify-string->seconds (prm :time)))
- (let ((period (org-notify-string->seconds (prm :period)))
- (last-run (prm last-run-sym)) (now (org-float-time))
- (actions (prm :actions)) diff plist)
- (when (or (not last-run)
- (and period (< period (setq diff (- now last-run)))
- (org-notify-maybe-too-late diff period heading)))
- (setq prms (plist-put prms last-run-sym now)
- plist (append todo prms))
- (if (if (plist-member prms :audible)
- (prm :audible)
- org-notify-audible)
- (ding))
- (unless (listp actions)
- (setq actions (list actions)))
- (dolist (action actions)
- (funcall (if (fboundp action) action
- (intern (concat "org-notify-action"
- (symbol-name action))))
- plist))))
- (return)))))))
+ (let ((notification-cnt 0))
+ (cl-macrolet ((prm (k) `(plist-get prms ,k)) (td (k) `(plist-get todo
,k)))
+ (dolist (todo (org-notify-todo-list))
+ (let* ((deadline (td :deadline)) (heading (td :heading))
+ (uid (td :uid)) (last-run-sym
+ (intern (concat ":last-run-" uid))))
+ (cl-dolist (prms (plist-get org-notify-map (td :notify)))
+ (when (< deadline (org-notify-string->seconds (prm :time)))
+ (let ((period (org-notify-string->seconds (prm :period)))
+ (last-run (prm last-run-sym)) (now (float-time))
+ (actions (prm :actions)) diff plist)
+ (when (or (not last-run)
+ (and period (< period (setq diff (- now last-run)))
+ (org-notify-maybe-too-late diff period
heading)))
+ (setq prms (plist-put prms last-run-sym now)
+ plist (append todo prms))
+ (if (if (plist-member prms :audible)
+ (prm :audible)
+ org-notify-audible)
+ (ding))
+ (unless (listp actions)
+ (setq actions (list actions)))
+ (cl-incf notification-cnt)
+ (dolist (action actions)
+ (funcall (if (fboundp action) action
+ (intern (concat "org-notify-action"
+ (symbol-name action))))
+ plist))
+ (when (>= notification-cnt
org-notify-max-notifications-per-run)
+ (cl-return-from org-notify-process))))
+ (cl-return))))))))
(defun org-notify-add (name &rest params)
- "Add a new notification type. The NAME can be used in Org-mode property
-`notify'. If NAME is `default', the notification type applies for todo items
-without the `notify' property. This file predefines such a default
+ "Add a new notification type.
+The NAME can be used in Org-mode property `notify'. If NAME is
+`default', the notification type applies for todo items without
+the `notify' property. This file predefines such a default
notification type.
Each element of PARAMS is a list with parameters for a given time
-distance to the deadline. This distance must increase from one element to
-the next.
+distance to the deadline. This distance must increase from one
+element to the next.
+
List of possible parameters:
+
:time Time distance to deadline, when this type of notification shall
- start. It's a string: an integral value (positive or negative)
+ start. It's a string: an integral value (positive or negative)
followed by a unit (s, m, h, d, w, M).
:actions A function or a list of functions to be called to notify the
- user. Instead of a function name, you can also supply a suffix
+ user. Instead of a function name, you can also supply a suffix
of one of the various predefined `org-notify-action-xxx'
functions.
- :period Optional: can be used to repeat the actions periodically. Same
- format as :time.
+ :period Optional: can be used to repeat the actions periodically.
+ Same format as :time.
:duration Some actions use this parameter to specify the duration of the
- notification. It's an integral number in seconds.
+ notification. It's an integral number in seconds.
:audible Overwrite the value of `org-notify-audible' for this action.
For the actions, you can use your own functions or some of the predefined
@@ -200,11 +226,12 @@ ones, whose names are prefixed with `org-notify-action-'."
(setq org-notify-map (plist-put org-notify-map name params)))
(defun org-notify-start (&optional secs)
- "Start the notification daemon. If SECS is positive, it's the
-period in seconds for processing the notifications of one
-org-agenda file, and if negative, notifications will be checked
-only when emacs is idle for -SECS seconds. The default value for
-SECS is 20."
+ "Start the notification daemon.
+If SECS is positive, it's the period in seconds for processing
+the notifications of one org-agenda file, and if negative,
+notifications will be checked only when emacs is idle for -SECS
+seconds. The default value for SECS is 20."
+ (interactive)
(if org-notify-timer
(org-notify-stop))
(setq secs (or secs 20)
@@ -216,8 +243,8 @@ SECS is 20."
(defun org-notify-stop ()
"Stop the notification daemon."
(when org-notify-timer
- (cancel-timer org-notify-timer)
- (setq org-notify-timer nil)))
+ (cancel-timer org-notify-timer)
+ (setq org-notify-timer nil)))
(defun org-notify-on-action (plist key)
"User wants to see action."
@@ -228,9 +255,10 @@ SECS is 20."
(switch-to-buffer (find-file-noselect file))
(org-with-wide-buffer
(goto-char begin)
- (show-entry))
+ (outline-show-entry))
(goto-char begin)
(search-forward "DEADLINE: <")
+ (search-forward ":")
(if (display-graphic-p)
(x-focus-frame nil)))
(save-excursion
@@ -251,7 +279,7 @@ SECS is 20."
(defun org-notify-on-action-button (button)
"User wants to see action after button activation."
- (macrolet ((get (k) `(button-get button ,k)))
+ (cl-macrolet ((get (k) `(button-get button ,k)))
(org-notify-on-action (get 'plist) (get 'key))
(org-notify-delete-window (get 'buffer))
(cancel-timer (get 'timer))))
@@ -294,12 +322,12 @@ SECS is 20."
(compose-mail user-mail-address (concat "TODO: " (plist-get plist :heading)))
(insert (org-notify-body-text plist))
(funcall send-mail-function)
- (flet ((yes-or-no-p (prompt) t))
+ (cl-letf (((symbol-function 'yes-or-no-p) (lambda (x) t)))
(kill-buffer)))
(defun org-notify-select-highest-window ()
"Select the highest window on the frame, that is not is not an
-org-notify window. Mostly copied from `appt-select-lowest-window'."
+org-notify window. Mostly copied from `appt-select-lowest-window'."
(let ((highest-window (selected-window))
(bottom-edge (nth 3 (window-edges)))
next-bottom-edge)
@@ -317,7 +345,7 @@ org-notify window. Mostly copied from
`appt-select-lowest-window'."
(defun org-notify-action-window (plist)
"Pop up a window, mostly copied from `appt-disp-window'."
(save-excursion
- (macrolet ((get (k) `(plist-get plist ,k)))
+ (cl-macrolet ((get (k) `(plist-get plist ,k)))
(let ((this-window (selected-window))
(buf (get-buffer-create
(format org-notify-window-buffer-name (get :uid)))))
@@ -356,6 +384,7 @@ org-notify window. Mostly copied from
`appt-select-lowest-window'."
:title (plist-get plist :heading)
:body (org-notify-body-text plist)
:timeout (if duration (* duration 1000))
+ :urgency (plist-get plist :urgency)
:actions org-notify-actions
:on-action 'org-notify-on-action-notify)))
(setq org-notify-on-action-map
@@ -370,7 +399,7 @@ terminal an emacs window."
;;; Provide a minimal default setup.
(org-notify-add 'default '(:time "1h" :actions -notify/window
- :period "2m" :duration 60))
+ :period "2m" :duration 60))
(provide 'org-notify)
- [elpa] externals/org-notify 704e023ad8 21/23: Simplify call to time-add in org-notify-body-text, (continued)
- [elpa] externals/org-notify 704e023ad8 21/23: Simplify call to time-add in org-notify-body-text, ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify f47c137a96 23/23: Add a todo list, ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify d24a1525c1 06/23: Remove obsolete org-notify-verbose., ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify d2e1c297fa 17/23: README.md: this module is no more in the org-mode distribution, ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify 3a9c55aabd 19/23: Fix package-lint errors, ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify d61af2d334 04/23: Use common prefix for all objects., ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify 75df171a0a 05/23: Allow also suffixes for predefined functions., ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify 13afc93024 08/23: Add support for sending emails., ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify dd342f86d6 11/23: org-notify-audible: new configuration variable., ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify 76f75705b3 13/23: org-notify-on-action: New action: show the entry., ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify 1c65ee9597 16/23: org-notify.el: update to version in org-mode distribution,
ELPA Syncer <=
- [elpa] externals/org-notify f566817937 10/23: New notification type: "notify or window"., ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify 5875631410 09/23: Treat only one file per call of org-notify-process., ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify 160c7eb64d 12/23: org-notify-body-text: Add time-stamp to text., ELPA Syncer, 2022/07/25
- [elpa] externals/org-notify e4bdac5a14 15/23: Create README.md, ELPA Syncer, 2022/07/25