diff --git a/lisp/files.el b/lisp/files.el index d5f60b7..603c014 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4512,24 +4512,42 @@ Before and after saving the buffer, this function runs "View the differences between BUFFER and its associated file. This requires the external program `diff' to be in your `exec-path'." (interactive "bBuffer: ") - (with-current-buffer (get-buffer (or buffer (current-buffer))) + (diff-buffer-internal (get-buffer (or buffer (current-buffer))) + (get-buffer-create "*Diff*")) + ;; return always nil, so that save-buffers-kill-emacs will not move + ;; over to the next unsaved buffer when calling `d'. + nil) + +(defvar diff-buffer-buffer) ;; suppress compiler warnings. + +(defun diff-buffer-internal (buffer result-buffer) + (if (not (and buffer (buffer-name buffer))) + (error "Original buffer deleted.")) + (with-current-buffer buffer (if (and buffer-file-name (file-exists-p buffer-file-name)) (let ((tempfile (make-temp-file "buffer-content-"))) (unwind-protect (progn (write-region nil nil tempfile nil 'nomessage) - (diff buffer-file-name tempfile nil t) - (sit-for 0)) + ;; No asynch so we don't delete the temp file prematurely. + (diff-into-buffer result-buffer buffer-file-name tempfile + nil t) + (sit-for 0) + ;; Now revise the revert-buffer-function, since the + ;; default will not be able to find the temp file. + (with-current-buffer result-buffer + (set (make-local-variable 'diff-buffer-buffer) buffer) + (setq revert-buffer-function + (lambda (ignore-auto noconfirm) + (diff-buffer-internal diff-buffer-buffer + (current-buffer)))))) (when (file-exists-p tempfile) (delete-file tempfile)))) (message "Buffer %s has no associated file on disc" (buffer-name)) ;; Display that message for 1 second so that user can read it ;; in the minibuffer. - (sit-for 1))) - ;; return always nil, so that save-buffers-kill-emacs will not move - ;; over to the next unsaved buffer when calling `d'. - nil) + (sit-for 1)))) (defvar save-some-buffers-action-alist `((?\C-r diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el index e79e72c..1a835b5 100644 --- a/lisp/vc/diff.el +++ b/lisp/vc/diff.el @@ -108,11 +108,16 @@ specified in `diff-switches' are passed to the diff command." (read-file-name "Diff original file: " (file-name-directory newf) nil t))) (list oldf newf (diff-switches)))) + (diff-into-buffer nil old new switches no-async)) + +(defun diff-into-buffer (buf old new &optional switches no-async) + ;; Noninteractive helper for creating and reverting diff buffers. (setq new (expand-file-name new) old (expand-file-name old)) (or switches (setq switches diff-switches)) ; If not specified, use default. + (or buf (setq buf (get-buffer-create "*Diff*"))) (let* ((old-alt (file-local-copy old)) - (new-alt (file-local-copy new)) + (new-alt (file-local-copy new)) (command (mapconcat 'identity `(,diff-command @@ -123,7 +128,6 @@ specified in `diff-switches' are passed to the diff command." ,(shell-quote-argument (or old-alt old)) ,(shell-quote-argument (or new-alt new))) " ")) - (buf (get-buffer-create "*Diff*")) (thisdir default-directory) proc) (save-excursion