* lisp/vc/diff-mode.el (diff-apply-buffer): New command (bug#66113).

(diff-mode-map): Bind 'diff-apply-buffer' to 'C-c C-m a'.
This commit is contained in:
Juri Linkov 2023-09-27 20:36:07 +03:00
parent 2d25f071b6
commit d813f71ffe
2 changed files with 39 additions and 0 deletions

View file

@ -321,6 +321,10 @@ This allows changing which type of whitespace changes are ignored when
regenerating hunks with 'diff-ignore-whitespace-hunk'. Defaults to
the previously hard-coded "-b".
*** New command 'diff-apply-buffer' bound to 'C-c RET a'.
It applies the diff in the entire diff buffer and
saves all modified file buffers.
** Isearch and Replace
*** New command 'replace-regexp-as-diff'.

View file

@ -216,6 +216,7 @@ The default \"-b\" means to ignore whitespace-only changes,
"C-x 4 A" #'diff-add-change-log-entries-other-window
;; Misc operations.
"C-c C-a" #'diff-apply-hunk
"C-c C-m a" #'diff-apply-buffer
"C-c C-e" #'diff-ediff-patch
"C-c C-n" #'diff-restrict-view
"C-c C-s" #'diff-split-hunk
@ -2054,6 +2055,40 @@ With a prefix argument, try to REVERSE the hunk."
(diff-hunk-kill)
(diff-hunk-next)))))
(defun diff-apply-buffer ()
"Apply the diff in the entire diff buffer.
When applying all hunks was successful, then save the changed buffers."
(interactive)
(let ((buffer-edits nil)
(failures 0)
(diff-refine nil))
(save-excursion
(goto-char (point-min))
(diff-beginning-of-hunk t)
(while (pcase-let ((`(,buf ,line-offset ,pos ,_src ,dst ,switched)
(diff-find-source-location nil nil)))
(cond ((and line-offset (not switched))
(push (cons pos dst)
(alist-get buf buffer-edits)))
(t (setq failures (1+ failures))))
(and (not (eq (prog1 (point) (ignore-errors (diff-hunk-next)))
(point)))
(looking-at-p diff-hunk-header-re)))))
(cond ((zerop failures)
(dolist (buf-edits (reverse buffer-edits))
(with-current-buffer (car buf-edits)
(dolist (edit (cdr buf-edits))
(let ((pos (car edit))
(dst (cdr edit))
(inhibit-read-only t))
(goto-char (car pos))
(delete-region (car pos) (cdr pos))
(insert (car dst))))
(save-buffer)))
(message "Saved %d buffers" (length buffer-edits)))
(t
(message "%d hunks failed; no buffers changed" failures)))))
(defalias 'diff-mouse-goto-source #'diff-goto-source)
(defun diff-goto-source (&optional other-file event)