[emacs] Fix org-reminders parsing of nested timed tasks

This commit is contained in:
2026-08-09 14:07:33 -04:00
parent b7b25e8d24
commit b14cc6b6c5

View File

@ -37,7 +37,7 @@
Avoids a backlog flood after the Emacs daemon was down.") Avoids a backlog flood after the Emacs daemon was down.")
(defvar org-reminder-default-interval "15m" (defvar org-reminder-default-interval "15m"
"Default reminder offset applied to every timed entry without a :REMINDER: property. "Default reminder offset for timed entries lacking a :REMINDER: property.
Set to \"none\" to disable the default entirely.") Set to \"none\" to disable the default entirely.")
(defvar org-reminder-state (make-hash-table :test 'equal) (defvar org-reminder-state (make-hash-table :test 'equal)
@ -92,7 +92,7 @@ The default interval is appended unless REM suppresses it."
"Regex matching a single active org timestamp.") "Regex matching a single active org timestamp.")
(defun org-reminder-first-inline-ts (limit) (defun org-reminder-first-inline-ts (limit)
"Return epoch seconds of the first active timestamp at or after point, before LIMIT." "Return epoch seconds of first active timestamp at/after point, before LIMIT."
(save-excursion (save-excursion
(let ((found nil)) (let ((found nil))
(while (and (not found) (while (and (not found)
@ -111,22 +111,23 @@ Each spec is (ID HEADING FIRE-TIME LABEL SECONDS)."
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward "^\\*+ " nil t) (while (re-search-forward "^\\*+ " nil t)
(let ((subtree-end (save-excursion (org-end-of-subtree t t)))) (let ((subtree-end (save-excursion (org-end-of-subtree t t))))
(when (and (org-get-todo-state) (not (org-entry-is-done-p))) (if (and (org-get-todo-state) (not (org-entry-is-done-p)))
(let* ((heading (string-trim (org-get-heading t t t t))) (let* ((heading (string-trim (org-get-heading t t t t)))
(id (or (org-entry-get nil "ID" t) (id (or (org-entry-get nil "ID" t)
(format "%s|%s" file heading))) (format "%s|%s" file heading)))
(rem (org-entry-get nil "REMINDER" t)) (rem (org-entry-get nil "REMINDER" t))
(anchor (progn (anchor (progn
(org-end-of-meta-data t) (org-end-of-meta-data t)
(org-reminder-first-inline-ts subtree-end)))) (org-reminder-first-inline-ts subtree-end))))
(when anchor (when anchor
(dolist (interval (org-reminder-task-intervals rem)) (dolist (interval (org-reminder-task-intervals rem))
(push (list id heading (push (list id heading
(- anchor (cdr interval)) (- anchor (cdr interval))
(car interval) (cdr interval)) (car interval) (cdr interval))
specs))))) specs)))
(goto-char subtree-end))))) (goto-char subtree-end))
(nreverse specs))) (goto-char (line-end-position))))))
(nreverse specs))))
(defun org-reminder-agenda-files () (defun org-reminder-agenda-files ()
"Return the list of agenda files, refreshing it (throttled) from vulpea." "Return the list of agenda files, refreshing it (throttled) from vulpea."
@ -227,7 +228,7 @@ Uses an mtime cache so unchanged files are not re-parsed."
(org-reminder-send (org-reminder-send
(format "Reminder: %s" heading) (format "Reminder: %s" heading)
(format "Due %s — %s away" (format "Due %s — %s away"
(format-time-string "%a %e %b %H:%M" (+ fire secs)) (format-time-string "%a %b %e %H:%M" (+ fire secs))
(org-reminder-human-delta (- (+ fire secs) now)))) (org-reminder-human-delta (- (+ fire secs) now))))
(puthash key now org-reminder-state) (puthash key now org-reminder-state)
(org-reminder-state-save) (org-reminder-state-save)