From 07ea05afab6e9d04bd0cc366df596b5faca3da0f Mon Sep 17 00:00:00 2001 From: hermione Date: Sun, 25 Jan 2026 14:20:44 -0800 Subject: [PATCH] feat(emacs): filter recurring events past CALDAV_UNTIL in agenda DEADLINE doesn't actually limit recurring event display in org-agenda. Instead, use org-agenda-skip-function-global to filter entries where today's date is past the CALDAV_UNTIL property. The skip function: - Checks for CALDAV_UNTIL property (set by caldav sync advice) - Parses YYYYMMDD format - Skips entry if today > UNTIL date This properly hides expired recurring events from the agenda. Co-Authored-By: Claude Opus 4.5 --- home/roles/emacs/doom/config.el | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/home/roles/emacs/doom/config.el b/home/roles/emacs/doom/config.el index 438d56f..a95099b 100644 --- a/home/roles/emacs/doom/config.el +++ b/home/roles/emacs/doom/config.el @@ -53,6 +53,22 @@ ;; change `org-directory'. It must be set before org loads! (setq org-directory "~/org/") (after! org + ;; Skip recurring events past their CALDAV_UNTIL date + ;; org-caldav ignores UNTIL from RRULE, so we store it as a property + ;; and filter here in the agenda + (defun my/skip-if-past-until () + "Return non-nil if entry has CALDAV_UNTIL and current date is past it." + (let ((until-str (org-entry-get nil "CALDAV_UNTIL"))) + (when (and until-str + (string-match "^\\([0-9]\\{4\\}\\)\\([0-9]\\{2\\}\\)\\([0-9]\\{2\\}\\)" until-str)) + (let* ((until-year (string-to-number (match-string 1 until-str))) + (until-month (string-to-number (match-string 2 until-str))) + (until-day (string-to-number (match-string 3 until-str))) + (until-time (encode-time 0 0 0 until-day until-month until-year)) + (today (current-time))) + (when (time-less-p until-time today) + (org-end-of-subtree t)))))) + (setq org-agenda-span 'week org-agenda-start-with-log-mode t my-agenda-dirs '("projects" "roam") @@ -61,6 +77,7 @@ "\.org$")) my-agenda-dirs)) org-log-done 'time + org-agenda-skip-function-global #'my/skip-if-past-until org-agenda-custom-commands '(("n" "Agenda" ((agenda "") (tags-todo "-someday-recurring")))