From 361a0488a67ffc601e207626b25327bf4868d24a Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Wed, 14 Sep 2016 21:08:07 +0200 Subject: [PATCH] Restore buffer in `pre-redisplay-functions' Previously, a function in `pre-redisplay-functions' could change the current buffer, breaking the contract of `pre-redisplay-functions' that the current buffer is always the buffer displayed in the argument window. * lisp/simple.el (redisplay--pre-redisplay-functions): Fix behavior when a function in `pre-redisplay-functions' changes the current buffer. * test/lisp/simple-tests.el (pre-redisplay-function--current-buffer): Test for fixed behavior. --- lisp/simple.el | 16 ++++++++++------ test/lisp/simple-tests.el | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lisp/simple.el b/lisp/simple.el index 04a525c..9a4690e 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5425,13 +5425,17 @@ pre-redisplay-functions is set to the buffer displayed in that window.") (defun redisplay--pre-redisplay-functions (windows) + (cond + ((null windows) (setq windows (list (selected-window)))) + ((nlistp windows) (setq windows (window-list-1 nil nil t)))) (with-demoted-errors "redisplay--pre-redisplay-functions: %S" - (if (null windows) - (with-current-buffer (window-buffer (selected-window)) - (run-hook-with-args 'pre-redisplay-functions (selected-window))) - (dolist (win (if (listp windows) windows (window-list-1 nil nil t))) - (with-current-buffer (window-buffer win) - (run-hook-with-args 'pre-redisplay-functions win)))))) + (dolist (win windows) + (run-hook-wrapped + 'pre-redisplay-functions + (lambda (func) + (with-current-buffer (window-buffer win) + (funcall func win)) + nil))))) (add-function :before pre-redisplay-function #'redisplay--pre-redisplay-functions) diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el index d022240..da7a03d 100644 --- a/test/lisp/simple-tests.el +++ b/test/lisp/simple-tests.el @@ -374,5 +374,33 @@ simple-test-undo-with-switched-buffer (undo) (point))))) + +;;; `pre-redisplay-function' +(ert-deftest pre-redisplay-function--current-buffer () + "Verify that the functions in `pre-redisplay-functions' are called with the correct `current-buffer'. +See Bug#21730." + (with-temp-buffer + (let ((buffer-1 (current-buffer))) + (with-temp-buffer + (let ((buffer-2 (current-buffer)) + (pre-redisplay-functions pre-redisplay-functions) + (hook-1-calls 0) + (hook-2-calls 0)) + (add-hook 'pre-redisplay-functions + (lambda (window) + (should (equal (current-buffer) (window-buffer window))) + (cl-incf hook-1-calls) + (set-buffer buffer-1)) + :append) + (add-hook 'pre-redisplay-functions + (lambda (window) + (should (equal (current-buffer) (window-buffer window))) + (cl-incf hook-2-calls)) + :append) + (funcall pre-redisplay-function nil) + (should (equal (current-buffer) buffer-2)) + (should (equal hook-1-calls 1)) + (should (equal hook-2-calls 1))))))) + (provide 'simple-test) ;;; simple-test.el ends here -- 2.8.0.rc3.226.g39d4020