diff options
| -rw-r--r-- | modules/org-agenda-config.el | 34 | ||||
| -rw-r--r-- | tests/test-org-agenda-config--base-files.el | 57 |
2 files changed, 62 insertions, 29 deletions
diff --git a/modules/org-agenda-config.el b/modules/org-agenda-config.el index d5d610f27..e20c7a6b5 100644 --- a/modules/org-agenda-config.el +++ b/modules/org-agenda-config.el @@ -47,9 +47,10 @@ ;; M-f8 - TASK LIST containing all tasks from just the current org-mode buffer. ;; ;; NOTE: -;; Files that contain information relevant to the agenda will be found in the -;; following places: the schedule-file, org-roam notes tagged as 'Projects' and -;; project todo.org files found in project-dir and code-dir. +;; Files that contain information relevant to the agenda are: the inbox, the +;; schedule-file, the synced calendars, and the per-project todo.org files found +;; in immediate subdirectories of projects-dir. (org-roam notes are refile +;; targets, not agenda sources -- see org-refile-config.el.) ;;; Code: (require 'user-constants) @@ -89,6 +90,12 @@ (setq org-agenda-skip-scheduled-if-done nil) (setq org-agenda-remove-tags t) (setq org-agenda-compact-blocks t) + ;; Backstop against a non-existent agenda file (e.g. a calendar not yet synced + ;; on a fresh machine): skip it silently instead of prompting to create it -- + ;; the interactive-prompt class that once hung the chime daemon. + ;; `cj/--org-agenda-base-files' already filters the list; this catches any path + ;; that reaches `org-agenda-files' another way. + (setq org-agenda-skip-unavailable-files t) ;; display the agenda from the bottom (add-to-list 'display-buffer-alist @@ -177,14 +184,18 @@ Only checks DIRECTORY/*/todo.org — does not recurse deeper." ;; ---------------------------- Rebuild Org Agenda --------------------------- ;; builds the org agenda list from all agenda targets with caching. -;; agenda targets is the schedule, contacts, project todos, -;; inbox, and org roam projects. +;; agenda targets are the inbox, the schedule, the synced calendars, +;; and the per-project todo.org files under projects-dir. (defun cj/--org-agenda-base-files () - "Return the fixed base files for the agenda: inbox, schedule, and calendars. + "Return the existing base files for the agenda: inbox, schedule, and calendars. The single source of the base list shared by the agenda builders and the chime initializer, so adding a calendar source is a one-place change. Per-project -todo.org files are layered on separately." - (list inbox-file schedule-file gcal-file pcal-file dcal-file)) +todo.org files are layered on separately. Files that do not exist are dropped +\(a fresh machine may lack the synced calendars or the inbox) so org-agenda +never prompts to create them -- the interactive-prompt class that once hung the +chime daemon; `org-agenda-skip-unavailable-files' is the backstop." + (seq-filter #'file-exists-p + (list inbox-file schedule-file gcal-file pcal-file dcal-file))) (defun cj/--org-agenda-scan-files () "Scan disk for the agenda files list. Pure-ish: no caching, no logging. @@ -243,8 +254,8 @@ Bypasses cache and scans directories from scratch." (defun cj/todo-list-all-agenda-files () "Displays an \\='org-agenda\\=' todo list. -The contents of the agenda will be built from org-project-files and org-roam -files that have project in their filetag." +The contents of the agenda are built from the base files (inbox, schedule, and +the synced calendars) plus the per-project todo.org files under projects-dir." (interactive) (cj/build-org-agenda-list) (org-agenda "a" "t")) @@ -385,8 +396,7 @@ This uses all org-agenda targets and presents three sections: - Today's schedule, including habits with consistency graphs - All priority B and C unscheduled/undeadlined tasks The agenda is rebuilt from all sources before display, including: -- inbox-file and schedule-file -- Org-roam nodes tagged as \"Project\" +- inbox-file, schedule-file, and the synced calendars - All todo.org files in immediate subdirectories of projects-dir" (interactive) (cj/build-org-agenda-list) diff --git a/tests/test-org-agenda-config--base-files.el b/tests/test-org-agenda-config--base-files.el index c6939b4d7..bd202a195 100644 --- a/tests/test-org-agenda-config--base-files.el +++ b/tests/test-org-agenda-config--base-files.el @@ -3,8 +3,11 @@ ;;; Commentary: ;; cj/--org-agenda-base-files is the single source of the fixed agenda base list ;; (inbox, schedule, and the three calendars) that was previously spelled out as -;; a literal in three places. The path vars are special (defvar'd in -;; user-constants), so they can be dynamically bound here. +;; a literal in three places. It now drops files that do not exist so org-agenda +;; never prompts to create a missing path (the hang class). The path vars are +;; special (defvar'd in user-constants), so they can be dynamically bound; tests +;; use real temp files for "exists" rather than mocking the `file-exists-p' +;; primitive. ;;; Code: @@ -13,24 +16,44 @@ (add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) (require 'org-agenda-config) -(ert-deftest test-org-agenda-base-files-returns-fixed-list-in-order () - "Normal: returns inbox, schedule, gcal, pcal, dcal in that order." - (let ((inbox-file "/i") - (schedule-file "/s") - (gcal-file "/g") - (pcal-file "/p") - (dcal-file "/d")) - (should (equal (cj/--org-agenda-base-files) - '("/i" "/s" "/g" "/p" "/d"))))) +(defun test-oa-base--tmp () + "Return a fresh existing temp file path." + (make-temp-file "oa-base-")) + +(ert-deftest test-org-agenda-base-files-returns-existing-in-order () + "Normal: returns inbox, schedule, gcal, pcal, dcal (all existing) in order." + (let* ((i (test-oa-base--tmp)) (s (test-oa-base--tmp)) (g (test-oa-base--tmp)) + (p (test-oa-base--tmp)) (d (test-oa-base--tmp)) + (inbox-file i) (schedule-file s) (gcal-file g) (pcal-file p) (dcal-file d)) + (unwind-protect + (should (equal (cj/--org-agenda-base-files) (list i s g p d))) + (dolist (f (list i s g p d)) (ignore-errors (delete-file f)))))) (ert-deftest test-org-agenda-base-files-reflects-current-values () "Boundary: the helper reads the vars at call time (not a captured snapshot)." - (let ((inbox-file "first") - (schedule-file "x") (gcal-file "x") (pcal-file "x") (dcal-file "x")) - (should (equal (car (cj/--org-agenda-base-files)) "first")) - (setq inbox-file "second") - (should (equal (car (cj/--org-agenda-base-files)) "second")) - (should (= (length (cj/--org-agenda-base-files)) 5)))) + (let* ((a (test-oa-base--tmp)) (b (test-oa-base--tmp)) + (inbox-file a) (schedule-file b) (gcal-file b) (pcal-file b) (dcal-file b)) + (unwind-protect + (progn + (should (equal (car (cj/--org-agenda-base-files)) a)) + (setq inbox-file b) + (should (equal (car (cj/--org-agenda-base-files)) b)) + (should (= (length (cj/--org-agenda-base-files)) 5))) + (ignore-errors (delete-file a)) + (ignore-errors (delete-file b))))) + +(ert-deftest test-org-agenda-base-files-drops-missing-files () + "Boundary/Error: files that do not exist are dropped, so a fresh machine +without synced calendars never hands org-agenda a path it would prompt to create." + (let* ((i (test-oa-base--tmp)) (s (test-oa-base--tmp)) + (inbox-file i) (schedule-file s) + (gcal-file "/no/such/gcal.org") + (pcal-file "/no/such/pcal.org") + (dcal-file "/no/such/dcal.org")) + (unwind-protect + (should (equal (cj/--org-agenda-base-files) (list i s))) + (ignore-errors (delete-file i)) + (ignore-errors (delete-file s))))) (provide 'test-org-agenda-config--base-files) ;;; test-org-agenda-config--base-files.el ends here |
