9

Looking for a solution on how to restore my window layout after an Ediff session, I found a blog post, where the author suggests:

(winner-mode)
(add-hook 'ediff-after-quit-hook-internal 'winner-undo)

This seems to almost work well for me. I say almost because I invoke M-x ediff-buffers from Helm, and quiting the Ediff session brings me back to the original layout with the dead Helm menu from where I chose M-x ediff-buffers.

Let me explain:

  1. At any point I have several windows open with a window layout L1.
  2. I want to ediff some buffers, so I press M-x: This re-uses one of the windows in L1 to open up a Helm autocompletion menu. So far so good.
  3. I choose ediff-buffers, and then the two buffers to compare, one after the other
  4. This takes me to an ediff session where I can check differences etc.
  5. Once I am done. I quit my ediff-session.
  6. I would like to go back to my layout L1 in step #1. However, Emacs (winner-mode) takes me back to step #2, where one of the Emacs windows in L1 was used to show the options in Helm. This is pointless since I am done with my ediff session.

How can I restore windows to my original layout L1?

Setup:

This is all in Emacs 25.0.50.1 on OS X. More specifically, GNU Emacs 25.0.50.1 (x86_64-apple-darwin14.0.0, NS appkit-1343.16 Version 10.10.1 (Build 14B25))

Amelio Vazquez-Reina
  • 5,157
  • 4
  • 32
  • 47

2 Answers2

12

What you want can be achieved cleanly using hook provided by ediff (which if read the documentation seem to be provided for this exact purpose), advices are not needed. The relevant hooks are

1) ediff-quit-hook, from the documentation

Hooks to run in the Ediff control buffer after finishing Ediff.

2) ediff-before-setup-hook

Hooks to run before Ediff begins to set up windows and buffers. This hook can be used to save the previous window config, which can be restored on ediff-quit or ediff-suspend.

The approach is similar to @abo-abo's approach. We save the window configuration before ediff is setup using the ediff-before-setup-hook and restore the stored window configuration in ediff-quit-hook.

(defvar my-ediff-last-windows nil)

(defun my-store-pre-ediff-winconfig ()
  (setq my-ediff-last-windows (current-window-configuration)))

(defun my-restore-pre-ediff-winconfig ()
  (set-window-configuration my-ediff-last-windows))

(add-hook 'ediff-before-setup-hook #'my-store-pre-ediff-winconfig)
(add-hook 'ediff-quit-hook #'my-restore-pre-ediff-winconfig)
Iqbal Ansari
  • 7,468
  • 1
  • 28
  • 31
5

Look at what you made me do, I was so happy with my ugly hack, and now it's fixed:

(defvar ediff-last-windows nil
  "Last ediff window configuration.")

(defun ediff-restore-windows ()
  "Restore window configuration to `ediff-last-windows'."
  (set-window-configuration ediff-last-windows)
  (remove-hook 'ediff-after-quit-hook-internal
               'ediff-restore-windows))

(defadvice ediff-buffers (around ediff-restore-windows activate)
  (setq ediff-last-windows (current-window-configuration))
  (add-hook 'ediff-after-quit-hook-internal 'ediff-restore-windows)
  ad-do-it)
abo-abo
  • 13,943
  • 1
  • 29
  • 43
  • 1
    My elisp knowledge is limited. What is the difference between this answer and the accepted one? Both do almost the same thing, but this one uses `defadvice` and seem to use `remove-hook`, that the other does not. Could you give a brief explanation? Thanks you! – nephewtom Nov 04 '17 at 21:34
  • 2
    It's better to avoid `defadvice` if possible. It's powerful, which makes it fast to come up with a quick solution, but in the end it's harder to maintain. – abo-abo Nov 06 '17 at 17:11
  • If it's better to avoid `defadvice`, then in the end, is the answer from @Iqbal answer better than the one from @abo-abo ? – glmorous Jan 07 '20 at 19:55
  • Seems "ad-do-it" is removed in the 26.3 manual. The doc for it is found in older manual https://ftp.gnu.org/old-gnu/Manuals/elisp-manual-21-2.8/html_chapter/elisp_17.html . – Talespin_Kit Apr 12 '21 at 18:10