[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master d813f71ffe6 2/2: * lisp/vc/diff-mode.el (diff-apply-buffer): New
From: |
Juri Linkov |
Subject: |
master d813f71ffe6 2/2: * lisp/vc/diff-mode.el (diff-apply-buffer): New command (bug#66113). |
Date: |
Wed, 27 Sep 2023 13:40:34 -0400 (EDT) |
branch: master
commit d813f71ffe62844f5d4cc97cb54f3877dcf55a06
Author: Juri Linkov <juri@linkov.net>
Commit: Juri Linkov <juri@linkov.net>
* 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'.
---
etc/NEWS | 4 ++++
lisp/vc/diff-mode.el | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/etc/NEWS b/etc/NEWS
index b82215bac65..18529c6fab3 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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'.
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index d776375d681..24a925eda73 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -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)