diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-22 19:43:00 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-22 19:43:00 -0500 |
| commit | f07ce74d835dfc81e1e529240526829464ad8b21 (patch) | |
| tree | cb6a18d1090fe2f6aeb72b9f7c076c647621f94f | |
| parent | bd7a8c8fe0ea0738a5461887e02eeb4e4050beb6 (diff) | |
| download | dotemacs-f07ce74d835dfc81e1e529240526829464ad8b21.tar.gz dotemacs-f07ce74d835dfc81e1e529240526829464ad8b21.zip | |
fix(org-roam): always save the daily after a journal task-copy
The save lived inside the `unless` branch that only ran when the completed task needed an `org-refile` into a different file. When the task was already in today's daily, the copy left the buffer modified but unsaved. A crash before the next manual save lost it, and shutdown prompted about the unsaved journal buffer.
I pulled the save out of the refile branch into a `cj/--org-roam-save-daily` helper that runs on both paths and only writes when the buffer is modified. Extracting it also makes the save logic testable without driving the org-roam capture machinery.
| -rw-r--r-- | modules/org-roam-config.el | 18 | ||||
| -rw-r--r-- | tests/test-org-roam-config-save-daily.el | 53 |
2 files changed, 66 insertions, 5 deletions
diff --git a/modules/org-roam-config.el b/modules/org-roam-config.el index 306c7fe2..0382976b 100644 --- a/modules/org-roam-config.el +++ b/modules/org-roam-config.el @@ -185,6 +185,15 @@ created in that subdirectory of `org-roam-directory'." ;; ------------------------ Org Roam Copy Done To Daily ------------------------ +(defun cj/--org-roam-save-daily (file) + "Save FILE's visiting buffer when it has unsaved changes. +Keeps a freshly-copied task off the unsaved-buffer prompt at shutdown and +guards against losing it to a crash." + (when-let ((target-buffer (find-buffer-visiting file))) + (with-current-buffer target-buffer + (when (buffer-modified-p) + (save-buffer))))) + (defun cj/org-roam-copy-todo-to-today () "Copy completed tasks to today's daily org-roam node." (interactive) @@ -204,11 +213,10 @@ created in that subdirectory of `org-roam-directory'." ;; Only refile if the target file is different than the current file (unless (equal (file-truename today-file) (file-truename (buffer-file-name))) - (org-refile nil nil (list "Completed Tasks" today-file nil pos)) - ;; Save explicitly so shutdown doesn't prompt about an unsaved journal buffer. - (when-let ((target-buffer (find-buffer-visiting today-file))) - (with-current-buffer target-buffer - (save-buffer)))))) + (org-refile nil nil (list "Completed Tasks" today-file nil pos))) + + ;; Save the daily whether or not a refile happened, so the copy survives. + (cj/--org-roam-save-daily today-file))) ;; ------------------------ Org-Branch To Org-Roam-Node ------------------------ diff --git a/tests/test-org-roam-config-save-daily.el b/tests/test-org-roam-config-save-daily.el new file mode 100644 index 00000000..f730eea5 --- /dev/null +++ b/tests/test-org-roam-config-save-daily.el @@ -0,0 +1,53 @@ +;;; test-org-roam-config-save-daily.el --- Tests for the daily-save helper -*- lexical-binding: t; -*- + +;;; Commentary: +;; `cj/--org-roam-save-daily' saves the daily's visiting buffer when it has +;; unsaved changes, so a freshly-copied completed task is never lost to a +;; crash and shutdown never prompts about an unsaved journal buffer. The save +;; runs whether or not the copy needed an `org-refile' (the previous version +;; only saved in the refile branch). `save-buffer' is stubbed (file-I/O +;; boundary) so the tests assert the modified-guard, not actual disk writes. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'org-roam-config) + +(ert-deftest test-org-roam-save-daily-saves-modified-buffer () + "Normal: a modified visiting buffer is saved." + (let ((f (make-temp-file "test-daily" nil ".org")) (saved 0)) + (unwind-protect + (progn + (with-current-buffer (find-file-noselect f) + (insert "x") (set-buffer-modified-p t)) + (cl-letf (((symbol-function 'save-buffer) + (lambda (&rest _) (cl-incf saved) (set-buffer-modified-p nil)))) + (cj/--org-roam-save-daily f)) + (should (= 1 saved))) + (when (find-buffer-visiting f) (kill-buffer (find-buffer-visiting f))) + (delete-file f)))) + +(ert-deftest test-org-roam-save-daily-skips-unmodified-buffer () + "Boundary: an unmodified visiting buffer is not saved." + (let ((f (make-temp-file "test-daily" nil ".org")) (saved 0)) + (unwind-protect + (progn + (with-current-buffer (find-file-noselect f) (set-buffer-modified-p nil)) + (cl-letf (((symbol-function 'save-buffer) (lambda (&rest _) (cl-incf saved)))) + (cj/--org-roam-save-daily f)) + (should (= 0 saved))) + (when (find-buffer-visiting f) (kill-buffer (find-buffer-visiting f))) + (delete-file f)))) + +(ert-deftest test-org-roam-save-daily-no-visiting-buffer-noop () + "Boundary: a file with no visiting buffer is a safe no-op." + (let ((saved 0)) + (cl-letf (((symbol-function 'save-buffer) (lambda (&rest _) (cl-incf saved)))) + (cj/--org-roam-save-daily "/nonexistent/no-buffer-here.org")) + (should (= 0 saved)))) + +(provide 'test-org-roam-config-save-daily) +;;; test-org-roam-config-save-daily.el ends here |
