aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-15 16:25:27 -0500
committerCraig Jennings <c@cjennings.net>2026-06-15 16:25:27 -0500
commit636e4d11de57e6e4c5618c2fa4371caff32e39a4 (patch)
tree90bf8861e76b6c28f7d7f3e499f1d7efee18c735
parent80e20cbf3030a321702bbe7f879e9de45afce028 (diff)
downloaddotemacs-636e4d11de57e6e4c5618c2fa4371caff32e39a4.tar.gz
dotemacs-636e4d11de57e6e4c5618c2fa4371caff32e39a4.zip
refactor(org-agenda): drop OVERDUE block, lead with the schedule
The daily F8 agenda opened with an OVERDUE block that re-listed every past-due scheduled or deadline task. Those items already show in the SCHEDULE block on today's line, since org-scheduled-past-days and org-deadline-past-days are both 10000. The OVERDUE section was pure duplication. I removed it and moved SCHEDULE to the top so the calendar leads the view. The now-dead cj/org-agenda-skip-subtree-if-not-overdue helper, its header defvar, and the nine tests covering it are gone too.
-rw-r--r--modules/org-agenda-config.el47
-rw-r--r--tests/test-org-agenda-config-commands.el18
-rw-r--r--tests/test-org-agenda-config-skip-functions.el81
3 files changed, 33 insertions, 113 deletions
diff --git a/modules/org-agenda-config.el b/modules/org-agenda-config.el
index e2b431f9a..704eaac9a 100644
--- a/modules/org-agenda-config.el
+++ b/modules/org-agenda-config.el
@@ -289,9 +289,6 @@ If the current buffer isn't an org buffer, inform the user."
(defvar cj/main-agenda-hipri-title "HIGH PRIORITY UNRESOLVED TASKS"
"String to announce the high priority section of the main agenda.")
-(defvar cj/main-agenda-overdue-title "OVERDUE"
- "String to announce the overdue section of the main agenda.")
-
(defvar cj/main-agenda-schedule-title "SCHEDULE"
"String to announce the schedule section of the main agenda.")
@@ -322,28 +319,6 @@ lands in one place.")
subtree-end
nil)))
-(defun cj/org-agenda-skip-subtree-if-not-overdue ()
- "Skip an agenda subtree if it is not an overdue deadline or scheduled task.
-An entry is considered overdue if it has a scheduled or deadline date strictly
-before today, is not marked as done, and is not a habit."
- (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
- (todo-state (org-get-todo-state))
- (style (org-entry-get nil "STYLE"))
- (deadline (org-entry-get nil "DEADLINE"))
- (scheduled (org-entry-get nil "SCHEDULED"))
- (today (org-time-string-to-absolute (format-time-string "%Y-%m-%d")))
- (deadline-day (and deadline (org-time-string-to-absolute deadline)))
- (scheduled-day (and scheduled (org-time-string-to-absolute scheduled))))
- (if (or (not todo-state) ; no todo keyword
- (member todo-state org-done-keywords) ; done/completed tasks
- (string= style "habit"))
- subtree-end ; skip if done or habit
- (let ((overdue (or (and deadline-day (< deadline-day today))
- (and scheduled-day (< scheduled-day today)))))
- (if overdue
- nil ; do not skip, keep this entry
- subtree-end))))) ; skip if not overdue
-
(defun cj/org-skip-subtree-if-priority (priority)
"Skip an agenda subtree if it has a priority of PRIORITY.
PRIORITY may be one of the characters ?A, ?B, or ?C."
@@ -364,19 +339,7 @@ KEYWORDS must be a list of strings."
(setq org-agenda-custom-commands
'(("d" "Daily Agenda with Tasks"
- ((alltodo ""
- ((org-agenda-skip-function #'cj/org-agenda-skip-subtree-if-not-overdue)
- (org-agenda-overriding-header cj/main-agenda-overdue-title)
- (org-agenda-prefix-format cj/--main-agenda-prefix-format)))
- (tags "PRIORITY=\"A\""
- ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
- (org-agenda-overriding-header cj/main-agenda-hipri-title)
- (org-agenda-prefix-format cj/--main-agenda-prefix-format)))
- (todo "VERIFY"
- ((org-agenda-skip-function 'cj/org-skip-subtree-if-habit)
- (org-agenda-overriding-header cj/main-agenda-verify-title)
- (org-agenda-prefix-format cj/--main-agenda-prefix-format)))
- (agenda ""
+ ((agenda ""
((org-agenda-start-day "0d")
(org-agenda-span 8)
(org-agenda-start-on-weekday nil)
@@ -386,6 +349,14 @@ KEYWORDS must be a list of strings."
'(org-agenda-skip-entry-if 'todo '("CANCELLED")))
(org-agenda-overriding-header cj/main-agenda-schedule-title)
(org-agenda-prefix-format cj/--main-agenda-prefix-format)))
+ (tags "PRIORITY=\"A\""
+ ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
+ (org-agenda-overriding-header cj/main-agenda-hipri-title)
+ (org-agenda-prefix-format cj/--main-agenda-prefix-format)))
+ (todo "VERIFY"
+ ((org-agenda-skip-function 'cj/org-skip-subtree-if-habit)
+ (org-agenda-overriding-header cj/main-agenda-verify-title)
+ (org-agenda-prefix-format cj/--main-agenda-prefix-format)))
(todo "DOING"
((org-agenda-skip-function 'cj/org-skip-subtree-if-habit)
(org-agenda-overriding-header cj/main-agenda-doing-title)
diff --git a/tests/test-org-agenda-config-commands.el b/tests/test-org-agenda-config-commands.el
index e29871b79..76407439d 100644
--- a/tests/test-org-agenda-config-commands.el
+++ b/tests/test-org-agenda-config-commands.el
@@ -145,6 +145,24 @@ calling `org-agenda'."
(should build-called)
(should (equal agenda-args '("a" "d")))))
+;;; org-agenda-custom-commands "d" daily structure
+
+(defun test-org-agenda--daily-blocks ()
+ "Return the block list of the \"d\" daily agenda command."
+ (nth 2 (assoc "d" org-agenda-custom-commands)))
+
+(ert-deftest test-org-agenda-daily-schedule-block-is-first ()
+ "Normal: the schedule (calendar) block leads the daily agenda."
+ (should (eq (car (nth 0 (test-org-agenda--daily-blocks))) 'agenda)))
+
+(ert-deftest test-org-agenda-daily-has-no-overdue-block ()
+ "Normal: no overdue block. It duplicated the past-due
+scheduled/deadline items the schedule block already surfaces on
+today's line (org-scheduled-past-days/org-deadline-past-days are
+large), so the standalone OVERDUE section was redundant."
+ (let ((flat (flatten-tree (test-org-agenda--daily-blocks))))
+ (should-not (memq 'cj/org-agenda-skip-subtree-if-not-overdue flat))))
+
;;; cj/add-timestamp-to-org-entry
(ert-deftest test-org-agenda-add-timestamp-inserts-on-next-line ()
diff --git a/tests/test-org-agenda-config-skip-functions.el b/tests/test-org-agenda-config-skip-functions.el
index aec1e71be..b8290da21 100644
--- a/tests/test-org-agenda-config-skip-functions.el
+++ b/tests/test-org-agenda-config-skip-functions.el
@@ -145,76 +145,6 @@ Suppresses org-mode hooks to avoid loading packages not available in batch."
(test-org-agenda--with-org-buffer "* DONE Finished task\n"
(should (integerp (cj/org-skip-subtree-if-keyword '("TODO" "DONE" "CANCELLED"))))))
-;;; ---------- cj/org-agenda-skip-subtree-if-not-overdue ----------
-
-;;; Normal Cases
-
-(ert-deftest test-org-agenda-config-skip-overdue-normal-past-scheduled-keeps ()
- "Entry scheduled in the past with TODO keyword is overdue — keep it."
- (test-org-agenda--with-org-buffer
- (concat "* TODO Overdue task\n"
- "SCHEDULED: " (test-org-timestamp-days-ago 7) "\n")
- (should (null (cj/org-agenda-skip-subtree-if-not-overdue)))))
-
-(ert-deftest test-org-agenda-config-skip-overdue-normal-future-scheduled-skips ()
- "Entry scheduled in the future is not overdue — skip it."
- (test-org-agenda--with-org-buffer
- (concat "* TODO Future task\n"
- "SCHEDULED: " (test-org-timestamp-days-ahead 7) "\n")
- (should (integerp (cj/org-agenda-skip-subtree-if-not-overdue)))))
-
-(ert-deftest test-org-agenda-config-skip-overdue-normal-past-deadline-keeps ()
- "Entry with past deadline and TODO keyword is overdue — keep it."
- (test-org-agenda--with-org-buffer
- (concat "* TODO Missed deadline\n"
- "DEADLINE: " (test-org-timestamp-days-ago 3) "\n")
- (should (null (cj/org-agenda-skip-subtree-if-not-overdue)))))
-
-(ert-deftest test-org-agenda-config-skip-overdue-normal-done-task-skips ()
- "Done task should be skipped even if overdue."
- (test-org-agenda--with-org-buffer
- (concat "* DONE Completed task\n"
- "SCHEDULED: " (test-org-timestamp-days-ago 7) "\n")
- (should (integerp (cj/org-agenda-skip-subtree-if-not-overdue)))))
-
-(ert-deftest test-org-agenda-config-skip-overdue-normal-habit-skips ()
- "Habit should be skipped even if overdue."
- (test-org-agenda--with-org-buffer
- (concat "* TODO Daily habit\n"
- "SCHEDULED: " (test-org-timestamp-days-ago 7) "\n"
- ":PROPERTIES:\n"
- ":STYLE: habit\n"
- ":END:\n")
- (should (integerp (cj/org-agenda-skip-subtree-if-not-overdue)))))
-
-(ert-deftest test-org-agenda-config-skip-overdue-normal-no-todo-keyword-skips ()
- "Entry without a TODO keyword should be skipped."
- (test-org-agenda--with-org-buffer
- (concat "* Just a heading\n"
- "SCHEDULED: " (test-org-timestamp-days-ago 7) "\n")
- (should (integerp (cj/org-agenda-skip-subtree-if-not-overdue)))))
-
-;;; Boundary Cases
-
-(ert-deftest test-org-agenda-config-skip-overdue-boundary-today-scheduled-skips ()
- "Entry scheduled today is NOT overdue (not strictly before today) — skip."
- (test-org-agenda--with-org-buffer
- (concat "* TODO Today task\n"
- "SCHEDULED: " (test-org-timestamp-today) "\n")
- (should (integerp (cj/org-agenda-skip-subtree-if-not-overdue)))))
-
-(ert-deftest test-org-agenda-config-skip-overdue-boundary-no-date-skips ()
- "Entry with TODO but no scheduled/deadline date — not overdue, skip."
- (test-org-agenda--with-org-buffer "* TODO Undated task\n"
- (should (integerp (cj/org-agenda-skip-subtree-if-not-overdue)))))
-
-(ert-deftest test-org-agenda-config-skip-overdue-boundary-future-deadline-skips ()
- "Entry with future deadline is not overdue — skip."
- (test-org-agenda--with-org-buffer
- (concat "* TODO Future deadline\n"
- "DEADLINE: " (test-org-timestamp-days-ahead 14) "\n")
- (should (integerp (cj/org-agenda-skip-subtree-if-not-overdue)))))
-
;;; ---------- "d" command SCHEDULE block: CANCELLED skip ----------
;;; Normal Cases
@@ -268,17 +198,18 @@ regression where one block diverges from the others on the format."
;;; Normal Cases
-(ert-deftest test-org-agenda-config-d-command-has-six-blocks-in-expected-order ()
- "Normal: the \"d\" command runs six blocks in the expected order --
-OVERDUE -> HIGH PRIORITY -> VERIFICATION -> SCHEDULE -> IN-PROGRESS -> PRIORITY B."
+(ert-deftest test-org-agenda-config-d-command-has-five-blocks-in-expected-order ()
+ "Normal: the \"d\" command runs five blocks in the expected order --
+SCHEDULE -> HIGH PRIORITY -> VERIFICATION -> IN-PROGRESS -> PRIORITY B.
+The schedule (calendar) leads; the former OVERDUE block was dropped
+because it duplicated the past-due items the schedule already shows."
(let* ((entry (assoc "d" org-agenda-custom-commands))
(blocks (nth 2 entry))
(shapes (mapcar (lambda (b) (list (car b) (cadr b))) blocks)))
(should (equal shapes
- '((alltodo "")
+ '((agenda "")
(tags "PRIORITY=\"A\"")
(todo "VERIFY")
- (agenda "")
(todo "DOING")
(alltodo ""))))))