aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--org-drill.el60
-rw-r--r--tests/test-org-drill-display-restore.el53
2 files changed, 93 insertions, 20 deletions
diff --git a/org-drill.el b/org-drill.el
index 489215a..f996f15 100644
--- a/org-drill.el
+++ b/org-drill.el
@@ -571,6 +571,11 @@ This can make text more readable for long-form content."
(defvar org-drill--saved-variable-pitch-mode nil
"Saved variable-pitch-mode state before drill session started.")
+(defvar org-drill--saved-display-buffer nil
+ "Buffer in which the active drill session set up its display.
+Captured at setup so restore can target the same buffer even if the
+user has switched away by the time `org-drill--restore-display' runs.")
+
(defvar org-drill-display-answer-hook nil
"Hook called when `org-drill' answers are displayed.")
@@ -1973,41 +1978,56 @@ overlay covering whatever range point happened to be at."
(defun org-drill--setup-display ()
"Set up display settings for drill session.
-Saves current settings and applies drill-specific display preferences."
- ;; Save current text scale and apply new size
+Saves current settings and applies drill-specific display preferences.
+Records the current buffer so that `org-drill--restore-display' can
+target it even if the user switches buffers mid-session."
+ (setq org-drill--saved-display-buffer (current-buffer))
+
+ ;; Save current text scale and apply new size (face is global).
(when org-drill-text-size-during-session
(setq org-drill--saved-text-scale
(face-attribute 'default :height nil 'default))
(set-face-attribute 'default nil :height (* org-drill-text-size-during-session 10)))
- ;; Save and enable variable-pitch mode
+ ;; Save and enable variable-pitch mode (buffer-local minor mode).
(when org-drill-use-variable-pitch
(setq org-drill--saved-variable-pitch-mode
(if (boundp 'variable-pitch-mode) variable-pitch-mode nil))
(variable-pitch-mode 1))
- ;; Save and hide modeline
+ ;; Save and hide modeline (buffer-local).
(when org-drill-hide-modeline-during-session
(setq org-drill--saved-modeline-format mode-line-format)
(setq-local mode-line-format nil)))
(defun org-drill--restore-display ()
- "Restore display settings after drill session ends."
- ;; Restore text size
- (when org-drill--saved-text-scale
- (set-face-attribute 'default nil :height org-drill--saved-text-scale)
- (setq org-drill--saved-text-scale nil))
-
- ;; Restore variable-pitch mode
- (when (and org-drill-use-variable-pitch
- (not (eq org-drill--saved-variable-pitch-mode 'unbound)))
- (variable-pitch-mode (if org-drill--saved-variable-pitch-mode 1 -1))
- (setq org-drill--saved-variable-pitch-mode nil))
-
- ;; Restore modeline
- (when org-drill--saved-modeline-format
- (setq-local mode-line-format org-drill--saved-modeline-format)
- (setq org-drill--saved-modeline-format nil)))
+ "Restore display settings after drill session ends.
+Buffer-local state (mode-line, variable-pitch-mode) is restored in
+the buffer the session originated from — not the current buffer at
+restore time, which may differ if the user switched away."
+ (let ((target (and (buffer-live-p org-drill--saved-display-buffer)
+ org-drill--saved-display-buffer)))
+ ;; Restore text size (face is global — no buffer targeting needed).
+ (when org-drill--saved-text-scale
+ (set-face-attribute 'default nil :height org-drill--saved-text-scale)
+ (setq org-drill--saved-text-scale nil))
+
+ ;; Restore variable-pitch-mode in the original buffer.
+ (when (and org-drill-use-variable-pitch
+ (not (eq org-drill--saved-variable-pitch-mode 'unbound)))
+ (when target
+ (with-current-buffer target
+ (variable-pitch-mode (if org-drill--saved-variable-pitch-mode 1 -1))))
+ (setq org-drill--saved-variable-pitch-mode nil))
+
+ ;; Restore modeline in the original buffer.
+ (when org-drill--saved-modeline-format
+ (when target
+ (with-current-buffer target
+ (setq-local mode-line-format org-drill--saved-modeline-format)))
+ (setq org-drill--saved-modeline-format nil))
+
+ (setq org-drill--saved-display-buffer nil)))
(defun org-drill-unhide-text ()
"Unhide text."
diff --git a/tests/test-org-drill-display-restore.el b/tests/test-org-drill-display-restore.el
new file mode 100644
index 0000000..90d1b0d
--- /dev/null
+++ b/tests/test-org-drill-display-restore.el
@@ -0,0 +1,53 @@
+;;; test-org-drill-display-restore.el --- Regression for cross-buffer display restore -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; The display setup / restore pair saved buffer-local state (mode-line,
+;; variable-pitch-mode) to global defvars and restored via plain
+;; `setq-local'. If the user switched buffers between setup and
+;; restore, the restore wrote to the wrong buffer — leaving the
+;; original drill buffer with its modeline still hidden, and trampling
+;; the destination buffer's modeline.
+;;
+;; The fix tracks the buffer at setup and uses `with-current-buffer'
+;; to restore in the original.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+(require 'org)
+(require 'org-drill)
+
+;;;; Cross-buffer modeline restore
+
+(ert-deftest test-display-restore-modeline-in-original-buffer-after-buffer-switch ()
+ "Setup in buffer A, restore in buffer B — A's mode-line should be restored,
+B's mode-line untouched."
+ (let ((buffer-a (generate-new-buffer "*org-drill-test-A*"))
+ (buffer-b (generate-new-buffer "*org-drill-test-B*"))
+ (org-drill-hide-modeline-during-session t)
+ (org-drill-text-size-during-session nil)
+ (org-drill-use-variable-pitch nil))
+ (unwind-protect
+ (progn
+ (with-current-buffer buffer-a
+ (setq-local mode-line-format "A-original")
+ (org-drill--setup-display)
+ ;; A's modeline is now hidden (nil).
+ (should (null mode-line-format)))
+ (with-current-buffer buffer-b
+ (setq-local mode-line-format "B-original")
+ ;; Restore runs from buffer B (simulating a buffer switch
+ ;; mid-session).
+ (org-drill--restore-display))
+ ;; After restore: A's modeline back to original, B's untouched.
+ (with-current-buffer buffer-a
+ (should (equal "A-original" mode-line-format)))
+ (with-current-buffer buffer-b
+ (should (equal "B-original" mode-line-format))))
+ (kill-buffer buffer-a)
+ (kill-buffer buffer-b))))
+
+(provide 'test-org-drill-display-restore)
+
+;;; test-org-drill-display-restore.el ends here