From e58f58b656cff9d9dc0e4b9fa59e236f0431e1b4 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Wed, 13 May 2026 16:14:50 -0500 Subject: refactor(org-agenda): extract main-agenda prefix format into a defvar `org-agenda-custom-commands` inlined ` %i %-15:c%?-15t% s` four times across the "d" command's overdue / high-priority / schedule / priority-B blocks. New `cj/--main-agenda-prefix-format` defvar holds the literal once; every block now references the symbol so a format tweak lands in one place. Regression test walks the "d" command's blocks and asserts each `org-agenda-prefix-format` cell resolves to the shared symbol -- a block that silently diverges fails the check. --- modules/org-agenda-config.el | 14 ++++++++++---- tests/test-org-agenda-config-skip-functions.el | 17 +++++++++++++++++ todo.org | 12 ++++++++++-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/modules/org-agenda-config.el b/modules/org-agenda-config.el index 2c30db0f..9ff2fd72 100644 --- a/modules/org-agenda-config.el +++ b/modules/org-agenda-config.el @@ -279,6 +279,12 @@ If the current buffer isn't an org buffer, inform the user." (defvar cj/main-agenda-tasks-title "PRIORITY B" "String to announce the schedule section of the main agenda.") +(defvar cj/--main-agenda-prefix-format " %i %-15:c%?-15t% s" + "Prefix format string shared by all blocks of the main daily agenda. +Inlined across the overdue / high-priority / schedule / priority-B +blocks of `org-agenda-custom-commands' before the extraction. Keep +the four blocks pointing here so a format tweak lands in one place.") + (defun cj/org-skip-subtree-if-habit () "Skip an agenda entry if it has a STYLE property equal to \"habit\"." (let ((subtree-end (save-excursion (org-end-of-subtree t)))) @@ -331,11 +337,11 @@ KEYWORDS must be a list of strings." ((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 " %i %-15:c%?-15t% s"))) + (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 " %i %-15:c%?-15t% s"))) + (org-agenda-prefix-format cj/--main-agenda-prefix-format))) (agenda "" ((org-agenda-start-day "0d") (org-agenda-span 8) @@ -345,7 +351,7 @@ KEYWORDS must be a list of strings." (org-agenda-skip-function '(org-agenda-skip-entry-if 'todo '("CANCELLED"))) (org-agenda-overriding-header cj/main-agenda-schedule-title) - (org-agenda-prefix-format " %i %-15:c%?-15t% s"))) + (org-agenda-prefix-format cj/--main-agenda-prefix-format))) (alltodo "" ((org-agenda-skip-function '(or (cj/org-skip-subtree-if-habit) (cj/org-skip-subtree-if-priority ?A) @@ -354,7 +360,7 @@ KEYWORDS must be a list of strings." (cj/org-skip-subtree-if-keyword '("PROJECT")) (org-agenda-skip-if nil '(scheduled deadline)))) (org-agenda-overriding-header cj/main-agenda-tasks-title) - (org-agenda-prefix-format " %i %-15:c%?-15t% s")))) + (org-agenda-prefix-format cj/--main-agenda-prefix-format)))) ((org-agenda-compact-blocks nil))))) diff --git a/tests/test-org-agenda-config-skip-functions.el b/tests/test-org-agenda-config-skip-functions.el index 17ee848f..3c044adb 100644 --- a/tests/test-org-agenda-config-skip-functions.el +++ b/tests/test-org-agenda-config-skip-functions.el @@ -247,5 +247,22 @@ priority-B blocks must not pick up the same skip-function form." (skip (cadr (assoc 'org-agenda-skip-function opts)))) (should-not (equal skip cancelled-form)))))) +;;; ---------- prefix-format extracted into a defvar ---------- + +;;; Normal Cases + +(ert-deftest test-org-agenda-config-prefix-format-extracted-to-defvar () + "Normal: every block of the \"d\" command references the shared prefix +format symbol rather than inlining the literal string. Catches a +regression where one block diverges from the others on the format." + (let* ((entry (assoc "d" org-agenda-custom-commands)) + (blocks (nth 2 entry))) + (should (boundp 'cj/--main-agenda-prefix-format)) + (should (stringp cj/--main-agenda-prefix-format)) + (dolist (b blocks) + (let* ((opts (nth 2 b)) + (fmt-form (cadr (assoc 'org-agenda-prefix-format opts)))) + (should (eq fmt-form 'cj/--main-agenda-prefix-format)))))) + (provide 'test-org-agenda-config-skip-functions) ;;; test-org-agenda-config-skip-functions.el ends here diff --git a/todo.org b/todo.org index 78eb448b..c2d88b2a 100644 --- a/todo.org +++ b/todo.org @@ -70,7 +70,7 @@ Decide whether to (a) leave it asymmetric and let the row fill in as new launchers arrive, (b) move an existing icon down to balance 5/5/2 or similar, or (c) reorganize by category (work / read / chat / play). Surfaced when Telegram landed in Row 3 alone. -** DOING [#A] Org Agenda fixes :bug: +** DONE [#A] Org Agenda fixes :bug: *** 2026-05-13 Wed @ 13:05:21 -0500 Skip CANCELLED entries from main agenda SCHEDULE see the following screenshot /home/cjennings/pictures/screenshots/2026-05-13_071428.png @@ -83,12 +83,20 @@ narrow -- DONE and FAILED scheduled tasks still render. Tests in =tests/test-org-agenda-config-skip-functions.el= (Normal + Boundary) lock in the configuration form on the agenda block and verify the other blocks aren't accidentally carrying the same skip. -*** TODO [#C] Refactor: extract org-agenda-prefix-format literal :refactor: +*** DONE [#C] Refactor: extract org-agenda-prefix-format literal :refactor: =modules/org-agenda-config.el= currently inlines =" %i %-15:c%?-15t% s"= across four blocks of =org-agenda-custom-commands= (overdue, hi-pri, schedule, priority-B). Extract into a defvar (e.g. =cj/--main-agenda-prefix-format=) and reference it from each block. Surfaced during the audit for the CANCELLED-schedule fix. + +Fix: new =cj/--main-agenda-prefix-format= defvar in +=modules/org-agenda-config.el=; all four blocks of the "d" command now +reference the symbol instead of inlining the literal. Regression test +in =tests/test-org-agenda-config-skip-functions.el= walks the blocks +and asserts each =org-agenda-prefix-format= entry resolves to the +shared symbol -- so a future tweak to one block can't silently diverge +from the others. *** 2026-05-13 Wed @ 13:27:39 -0500 Clear dedicated before toggling window split Reproduction steps - open an org file (I was using this projects's todo.org file -- cgit v1.2.3