Yoo
Yoo

Reputation: 18346

Using ediff with C-x s (save-some-buffers) in Emacs?

C-x s uses diff to show changes. How can I use ediff instead?

Upvotes: 2

Views: 509

Answers (2)

phils
phils

Reputation: 73274

I can see a couple of approaches to doing this. The first is to replace the save-some-buffers-action-alist variable with modified code, which is more straightforward. The second is to advise save-some-buffers and redefine the functions called by those actions, but that's a bit trickier.

I tried it both ways, and I think this is the best option:

;; Use ediff instead of diff in `save-some-buffers'
(eval-after-load "files"
  '(progn
     (setcdr (assq ?d save-some-buffers-action-alist)
             `(,(lambda (buf)
                  (if (null (buffer-file-name buf))
                      (message "Not applicable: no file")
                    (add-hook 'ediff-after-quit-hook-internal
                              'my-save-some-buffers-with-ediff-quit t)
                    (save-excursion
                      (set-buffer buf)
                      (let ((enable-recursive-minibuffers t))
                        (ediff-current-file)
                        (recursive-edit))))
                  ;; Return nil to ask about BUF again.
                  nil)
               ,(purecopy "view changes in this buffer")))

     (defun my-save-some-buffers-with-ediff-quit ()
       "Remove ourselves from the ediff quit hook, and
return to the save-some-buffers minibuffer prompt."
       (remove-hook 'ediff-after-quit-hook-internal
                    'my-save-some-buffers-with-ediff-quit)
       (exit-recursive-edit))))

My attempt at using advice is flawed (it breaks the C-r behaviour which also calls view-buffer, which caused me to reconsider using advice for this purpose), but FWIW:

(defadvice save-some-buffers (around my-save-some-buffers-with-ediff)
  "Use ediff instead of diff."
  (require 'cl)
  (flet ((view-buffer (&rest) nil)
         (diff-buffer-with-file
          (buf)
          (add-hook 'ediff-after-quit-hook-internal
                    'my-save-some-buffers-with-ediff-quit t)
          (save-excursion
            (set-buffer buf)
            (ediff-current-file))))
    (let ((enable-recursive-minibuffers t))
      ad-do-it)))
(ad-activate 'save-some-buffers)

(defun my-save-some-buffers-with-ediff-quit ()
  "Remove ourselves from the ediff quit hook, and
    return to the save-some-buffers minibuffer prompt."
  (remove-hook 'ediff-after-quit-hook-internal
               'my-save-some-buffers-with-ediff-quit)
  (exit-recursive-edit))

Upvotes: 3

vpit3833
vpit3833

Reputation: 7951

The variable diff-command is customizable, says the documentation. However, remember that it points to an external program, and not an elisp function. ediff is an elisp function that is in ediff.el. You might have to edit diff.el to (require 'ediff) and then tweak here and there in diff.el to see that you break nothing else.

Upvotes: 1

Related Questions