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))

up vote 6 down vote accepted

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)

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)
  • Works like a charm. Thanks! – Amelio Vazquez-Reina Jan 19 '15 at 19:07
  • 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 4 '17 at 21:34
  • 1
    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 6 '17 at 17:11

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.