diff options
| -rw-r--r-- | modules/org-agenda-config.el | 47 | ||||
| -rw-r--r-- | tests/test-org-agenda-config-commands.el | 18 | ||||
| -rw-r--r-- | tests/test-org-agenda-config-skip-functions.el | 81 |
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 "")))))) |
