Subject: bug#78897: closed (Re: bug#78897: Ediff 2.81.6; Window restoration with ediff-before-setup-hook doesn't work for ediff-regions-linewise)

From: [email-masked] (GNU bug Tracking System)
Date: Sat, 05 Jul 2025 08:10:03 +0000

Your bug report

#78897: Ediff 2.81.6; Window restoration with ediff-before-setup-hook doesn't work for ediff-regions-linewise

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
78897: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=78897
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#78897: Ediff 2.81.6; Window restoration with ediff-before-setup-hook doesn't work for ediff-regions-linewise
From: Eli Zaretskii <[email-masked]>
To: Aaron Zeng <[email-masked]>
Cc: [email-masked], [email-masked], [email-masked]
Date: Sat, 05 Jul 2025 11:09:03 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

> Cc: [email-masked]
> Date: Wed, 25 Jun 2025 16:40:51 -0400
> From:  Aaron Zeng via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <[email-masked]>
> 
> ediff-before-setup-hook's docstring suggests using it to save and
> restore the window configuration prior to invoking an Ediff command.
> Users at my site have an equivalent to the following hooks:
> 
> (defvar my-saved-window-configuration nil)
> (add-hook 'ediff-before-setup-hook
>           (lambda ()
>             (setq my-saved-window-configuration (current-window-configuration))))
> (add-hook 'ediff-quit-hook
>           (lambda ()
>             (set-window-configuration my-saved-window-configuration)
>             (setq my-saved-window-configuration nil)))
> 
> This works fine for most Ediff commands but does not work correctly
> with ediff-regions-linewise and ediff-regions-wordwise.  You can
> reproduce the behavior from emacs -Q:
> 
> 1. emacs -Q
> 2. Evaluate the above snippet
> 3. M-x ediff-regions-linewise (select an arbitrary pair of buffers and
>    regions like selecting *scratch* twice)
> 4. Press q
> 
> After quitting, the original window configuration is not restored.  In
> particular, the window is split vertically with a short window below
> the selected taller one.
> 
> I believe this is because those commands use
> ediff-clone-buffer-for-region-comparison to prompt for regions as diff
> input, and that involves adjusting the window configuration a few
> times.  The following patch seems to fix the behavior (edited to
> remove the indentation diff for brevity):

Thanks, I've now installed this on the master branch, and I'm
therefore closing this bug.

Subject: Ediff 2.81.6; Window restoration with ediff-before-setup-hook doesn't work for ediff-regions-linewise
From: Aaron Zeng <[email-masked]>
To: [email-masked], [email-masked]
Cc: [email-masked]
Date: Wed, 25 Jun 2025 16:40:51 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

ediff-before-setup-hook's docstring suggests using it to save and
restore the window configuration prior to invoking an Ediff command.
Users at my site have an equivalent to the following hooks:

(defvar my-saved-window-configuration nil)
(add-hook 'ediff-before-setup-hook
          (lambda ()
            (setq my-saved-window-configuration (current-window-configuration))))
(add-hook 'ediff-quit-hook
          (lambda ()
            (set-window-configuration my-saved-window-configuration)
            (setq my-saved-window-configuration nil)))

This works fine for most Ediff commands but does not work correctly
with ediff-regions-linewise and ediff-regions-wordwise.  You can
reproduce the behavior from emacs -Q:

1. emacs -Q
2. Evaluate the above snippet
3. M-x ediff-regions-linewise (select an arbitrary pair of buffers and
   regions like selecting *scratch* twice)
4. Press q

After quitting, the original window configuration is not restored.  In
particular, the window is split vertically with a short window below
the selected taller one.

I believe this is because those commands use
ediff-clone-buffer-for-region-comparison to prompt for regions as diff
input, and that involves adjusting the window configuration a few
times.  The following patch seems to fix the behavior (edited to
remove the indentation diff for brevity):

diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el
index a2c9b6f50ec..16878cf779f 100644
--- a/lisp/vc/ediff-util.el
+++ b/lisp/vc/ediff-util.el
@@ -3247,6 +3247,7 @@ ediff-save-buffer
 
 ;; idea suggested by Hannu Koivisto <[email-masked]>
 (defun ediff-clone-buffer-for-region-comparison (buff region-name)
+  (save-window-excursion
     (let ((cloned-buff (ediff-make-cloned-buffer buff region-name))
 	  (pop-up-windows t)
 	  wind
@@ -3285,7 +3286,7 @@ ediff-clone-buffer-for-region-comparison
 	  (quit
 	   (ediff-kill-buffer-carefully cloned-buff)))
         )
-    cloned-buff))
+      cloned-buff)))

 (defun ediff-clone-buffer-for-window-comparison (buff wind region-name)

The generated output below reflects my site's actual default config,
but the reproduction steps above work with Emacs's defaults.

Emacs  : GNU Emacs 30.1.90 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo version 1.15.12, Xaw scroll bars)
 of 2025-06-25
Package: Ediff 2.81.6

current state:
==============
(setq
 ediff-diff-program "diff"
 ediff-diff-options ""
 ediff-diff3-program "diff3"
 ediff-diff3-options ""
 ediff-patch-program "patch"
 ediff-patch-options "-f"
 ediff-shell "sh"
 ediff-use-faces t
 ediff-auto-refine 'on
 ediff-highlighting-style 'face
 ediff-buffer-A nil
 ediff-buffer-B nil
 ediff-control-buffer nil
 ediff-forward-word-function 'ediff-forward-word
 ediff-control-frame nil
 ediff-control-frame-parameters '((name . "Ediff") (minibuffer) (user-position . t) (vertical-scroll-bars) (menu-bar-lines . 0)
                                  (tool-bar-lines . 0) (left-fringe . 0) (right-fringe . 0) (auto-lower) (auto-raise . t) (visibility)
                                  (width . 1) (height . 1) (fullscreen) (top . 4321) (left . 3841))
 ediff-control-frame-position-function 'ediff-make-frame-position
 ediff-prefer-iconified-control-frame nil
 ediff-window-setup-function 'ediff-setup-windows-plain
 ediff-split-window-function 'split-window-horizontally
 ediff-job-name nil
 ediff-word-mode nil
 ediff-buffer-name " *ediff-message*"
 window-system 'x
 )