aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-05 05:23:34 -0500
committerCraig Jennings <c@cjennings.net>2026-05-05 05:23:34 -0500
commitbac40a5dbc241cab055f92431a80b7971896fde4 (patch)
tree304ab69cdeecba695137043644ab9a8659dbecac
parent6afd53b644c9b1fe0592892464c2d7fb37fa29e7 (diff)
downloadorg-drill-bac40a5dbc241cab055f92431a80b7971896fde4.tar.gz
org-drill-bac40a5dbc241cab055f92431a80b7971896fde4.zip
fix: clear stale end-pos on resume so final-report fires (upstream #33)
When a user interrupted a drill session to edit or capture, the session's end-pos slot got set to a marker (or :quit). The end-of- org-drill cond branched on end-pos: if set, show resume message and skip org-drill-final-report. That worked for the first interruption. But on org-drill-resume, the session was reused with end-pos still carrying the prior marker. Even when the resumed session completed normally, the same cond branch fired again — silently skipping final-report. Clear end-pos at the top of org-drill when resume-p is non-nil, per Markus's proposed patch on the upstream issue. The resumed session can now reach the final-report branch.
-rw-r--r--org-drill.el7
-rw-r--r--tests/test-org-drill-resume-clears-end-pos.el57
2 files changed, 64 insertions, 0 deletions
diff --git a/org-drill.el b/org-drill.el
index f996f15..6872d29 100644
--- a/org-drill.el
+++ b/org-drill.el
@@ -3150,6 +3150,13 @@ work correctly with older versions of org mode. Your org mode version (%s) appea
(setq org-drill-last-session
(org-drill-session)))))
(cl-block org-drill
+ ;; Clear stale `end-pos' on resume. The slot was set when the
+ ;; user interrupted the previous session (edit / quit), and
+ ;; carrying it over makes the post-resume `(if (oref session
+ ;; end-pos) ...)' branch fire — silently skipping
+ ;; `org-drill-final-report' (upstream issue #33).
+ (when resume-p
+ (setf (oref session end-pos) nil))
(unless resume-p
(org-drill-free-markers session t)
(setf (oref session cram-mode) cram
diff --git a/tests/test-org-drill-resume-clears-end-pos.el b/tests/test-org-drill-resume-clears-end-pos.el
new file mode 100644
index 0000000..3f3e1b8
--- /dev/null
+++ b/tests/test-org-drill-resume-clears-end-pos.el
@@ -0,0 +1,57 @@
+;;; test-org-drill-resume-clears-end-pos.el --- Regression for #33 -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Upstream issue #33 (2020-05). When a user interrupted a drill
+;; session to edit or capture, `org-drill-entries' set the session's
+;; `end-pos' slot. The end-of-`org-drill' cond branched on `end-pos':
+;; if set, show "you can resume" and skip `org-drill-final-report'.
+;;
+;; That worked for the first interruption. But on subsequent
+;; `org-drill-resume', the session was reused with `end-pos' still
+;; carrying the marker from before — so even when the resumed session
+;; completed normally, `final-report' was still skipped.
+;;
+;; Fix: clear `end-pos' at the top of `org-drill' when resume-p is
+;; non-nil, so the session can again reach the final-report branch.
+;; This matches Markus's proposed patch on the upstream issue.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+(require 'org)
+(require 'org-drill)
+
+;;;; Regression — #33
+
+(ert-deftest test-org-drill-resume-clears-stale-end-pos ()
+ "An org-drill resume on a session whose end-pos is still set from a
+prior interruption should clear end-pos so the resumed session can
+reach the normal final-report branch."
+ (let ((session (org-drill-session))
+ (final-report-called nil))
+ ;; Simulate a session that was interrupted by edit (end-pos = marker).
+ (let ((stale-marker (with-temp-buffer (point-marker))))
+ (oset session end-pos stale-marker))
+ (oset session start-time (float-time (current-time)))
+ ;; Set up org-drill-last-session for the resume path to find.
+ (let ((org-drill-last-session session))
+ (cl-letf (((symbol-function 'org-drill-final-report)
+ (lambda (_) (setq final-report-called t)))
+ ((symbol-function 'org-drill--setup-display) #'ignore)
+ ((symbol-function 'org-drill--restore-display) #'ignore)
+ ((symbol-function 'org-drill-map-entries) #'ignore)
+ ((symbol-function 'org-drill-order-overdue-entries) #'ignore)
+ ((symbol-function 'org-drill-entries)
+ (lambda (_session &optional _resume) nil))
+ ((symbol-function 'org-drill-free-markers) #'ignore)
+ ((symbol-function 'persist-save) #'ignore)
+ ((symbol-function 'sit-for) #'ignore))
+ (org-drill nil nil t nil)
+ ;; The resumed session completed normally — end-pos cleared,
+ ;; final-report fired.
+ (should final-report-called)))))
+
+(provide 'test-org-drill-resume-clears-end-pos)
+
+;;; test-org-drill-resume-clears-end-pos.el ends here