1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

Improve ibuffer-diff-with-file

* lisp/ibuf-ext.el (ibuffer-diff-with-file): Link to diff-command in
docstring.  Make Diff buffer read-only from outset and inhibit as
needed to avoid surprises.  Check whether diff-command
supports --label.  Leave point at BOB and clean up any excess
newline inserted by ibuffer-diff-buffer-with-file-1.  Prefer
pop-to-buffer-same-window over switch-to-buffer.

(ibuffer-diff-buffer-with-file-1): Add docstring.  Remove unused
unwind-protect and copypasta from diff-no-select (bug#62599).  Use
diff-file-local-copy, string-join, and redisplay in place of
analogues.  Condition --label use on availability, and label buffers
consistently with diff-no-select.  Leave empty line between runs.
Let diff-sentinel delete temporary files.  Leave point at EOB for
next run.
This commit is contained in:
Basil L. Contovounesios 2023-04-01 15:14:34 +01:00
parent 9848ae1716
commit 10b58633b5

View file

@ -1650,68 +1650,67 @@ a prefix argument reverses the meaning of that variable."
(error "No buffer with name %s" name)
(goto-char buf-point)))))
(declare-function diff-check-labels "diff" (&optional force))
(declare-function diff-file-local-copy "diff" (file-or-buf))
(declare-function diff-sentinel "diff"
(code &optional old-temp-file new-temp-file))
(defun ibuffer-diff-buffer-with-file-1 (buffer)
(let ((bufferfile (buffer-local-value 'buffer-file-name buffer))
(tempfile (make-temp-file "buffer-content-")))
(when bufferfile
(unwind-protect
(progn
(with-current-buffer buffer
(write-region nil nil tempfile nil 'nomessage))
(let* ((old (expand-file-name bufferfile))
(new (expand-file-name tempfile))
(oldtmp (file-local-copy old))
(newtmp (file-local-copy new))
"Compare BUFFER with its associated file, if any.
Unlike `diff-no-select', insert output into current buffer
without erasing it."
(when-let ((old (buffer-file-name buffer)))
(defvar diff-use-labels)
(let* ((new buffer)
(oldtmp (diff-file-local-copy old))
(newtmp (diff-file-local-copy new))
(switches diff-switches)
(command
(mapconcat
'identity
(string-join
`(,diff-command
;; Use explicitly specified switches
,@(if (listp switches) switches (list switches))
,@(if (or old new)
(list "-L" (shell-quote-argument old)
"-L" (shell-quote-argument
(format "Buffer %s" (buffer-name buffer)))))
,@(and (eq diff-use-labels t)
(list "--label" (shell-quote-argument old)
"--label" (shell-quote-argument (format "%S" new))))
,(shell-quote-argument (or oldtmp old))
,(shell-quote-argument (or newtmp new)))
" ")))
(let ((inhibit-read-only t))
(insert command "\n")
(diff-sentinel
(call-process shell-file-name nil
(current-buffer) nil
shell-command-switch command))
(insert "\n")))))
(sit-for 0)
(when (file-exists-p tempfile)
(delete-file tempfile)))))
" "))
(inhibit-read-only t))
(insert ?\n command ?\n)
(diff-sentinel (call-process shell-file-name nil t nil
shell-command-switch command)
oldtmp newtmp)
(goto-char (point-max)))
(redisplay)))
;;;###autoload
(defun ibuffer-diff-with-file ()
"View the differences between marked buffers and their associated files.
If no buffers are marked, use buffer at point.
This requires the external program \"diff\" to be in your `exec-path'."
This requires the external program `diff-command' to be in your
`exec-path'."
(interactive)
(require 'diff)
(let ((marked-bufs (ibuffer-get-marked-buffers)))
(when (null marked-bufs)
(setq marked-bufs (list (ibuffer-current-buffer t))))
(with-current-buffer (get-buffer-create "*Ibuffer Diff*")
(setq buffer-read-only nil)
(buffer-disable-undo (current-buffer))
(erase-buffer)
(buffer-enable-undo (current-buffer))
(let ((marked-bufs (or (ibuffer-get-marked-buffers)
(list (ibuffer-current-buffer t))))
(diff-buf (get-buffer-create "*Ibuffer Diff*")))
(with-current-buffer diff-buf
(setq buffer-read-only t)
(buffer-disable-undo)
(let ((inhibit-read-only t))
(erase-buffer))
(buffer-enable-undo)
(diff-mode)
(diff-check-labels)
(dolist (buf marked-bufs)
(unless (buffer-live-p buf)
(error "Buffer %s has been killed" buf))
(ibuffer-diff-buffer-with-file-1 buf))
(setq buffer-read-only t)))
(switch-to-buffer "*Ibuffer Diff*"))
(goto-char (point-min))
(when (= (following-char) ?\n)
(let ((inhibit-read-only t))
(delete-char 1))))
(pop-to-buffer-same-window diff-buf)))
;;;###autoload
(defun ibuffer-copy-filename-as-kill (&optional arg)