aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Whitton2024-09-24 09:38:43 +0100
committerSean Whitton2024-09-26 11:51:21 +0100
commitf2e3e563d4909ff503bb2d3aeb6d2de9804e3047 (patch)
tree6aa69bb519fcbd421e62adcd5b7cf3057637b631
parent8ffb680d09bc6b18d36941765e0f4ca881b565c9 (diff)
downloademacs-f2e3e563d4909ff503bb2d3aeb6d2de9804e3047.tar.gz
emacs-f2e3e563d4909ff503bb2d3aeb6d2de9804e3047.zip
New command diff-revert-and-kill-hunk
* lisp/vc/diff-mode.el (diff-revert-and-kill-hunk): New command (bug#73407). (diff-ask-before-revert-and-kill-hunk): New user option. (diff-apply-buffer): New optional BEG, END and REVERSE arguments. Return nil if buffers were saved, or the number of failed applications. (diff-mode-map): Bind the new command to C-c M-r. (diff-mode-menu): New entry for the new command. * doc/emacs/files.texi (Diff Mode): * etc/NEWS: Document the change.
-rw-r--r--doc/emacs/files.texi15
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/vc/diff-mode.el45
3 files changed, 59 insertions, 6 deletions
diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi
index 709cb0910e6..b7d6b6f9f7b 100644
--- a/doc/emacs/files.texi
+++ b/doc/emacs/files.texi
@@ -1682,6 +1682,21 @@ reverse of the hunk, which changes the ``new'' version into the ``old''
1682version. If @code{diff-jump-to-old-file} is non-@code{nil}, apply the 1682version. If @code{diff-jump-to-old-file} is non-@code{nil}, apply the
1683hunk to the ``old'' version of the file instead. 1683hunk to the ``old'' version of the file instead.
1684 1684
1685@findex diff-revert-and-kill-hunk
1686@item C-c M-r
1687Reverse-apply this hunk to the target file, and then kill it
1688(@code{diff-revert-and-kill-hunk}). Save the buffer visiting the target
1689file.
1690
1691This command is useful in buffers generated by @w{@kbd{C-x v =}} and
1692@w{@kbd{C-x v D}} (@pxref{Old Revisions}). These buffers present you
1693with a view of the changes you've made, and then you can use this
1694command to drop changes you didn't intend, or no longer want.
1695
1696This is a destructive operation, so by default, this command asks you to
1697confirm you really want to reverse-apply and kill the hunk. You can
1698customize @code{diff-ask-before-revert-and-kill-hunk} to change that.
1699
1685@findex diff-apply-buffer 1700@findex diff-apply-buffer
1686@item C-c @key{RET} a 1701@item C-c @key{RET} a
1687Apply all the hunks in the buffer (@code{diff-apply-buffer}). If the 1702Apply all the hunks in the buffer (@code{diff-apply-buffer}). If the
diff --git a/etc/NEWS b/etc/NEWS
index 2241f0f9a4a..feadc54c17a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -363,6 +363,11 @@ according to diffs in the current buffer, but without applying the diffs
363to the original text. If the selected range extends a hunk, the 363to the original text. If the selected range extends a hunk, the
364command attempts to look up and copy the text in-between the hunks. 364command attempts to look up and copy the text in-between the hunks.
365 365
366+++
367*** New command 'diff-revert-and-kill-hunk' bound to C-c M-r.
368This command reverse-applies the hunk at point, and then kills it.
369This is useful in buffers generated by C-x v = and C-x v D.
370
366** php-ts-mode 371** php-ts-mode
367 372
368--- 373---
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index b8a9484627c..c59c0954ae1 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -218,6 +218,7 @@ The default \"-b\" means to ignore whitespace-only changes,
218 "C-x 4 A" #'diff-add-change-log-entries-other-window 218 "C-x 4 A" #'diff-add-change-log-entries-other-window
219 ;; Misc operations. 219 ;; Misc operations.
220 "C-c C-a" #'diff-apply-hunk 220 "C-c C-a" #'diff-apply-hunk
221 "C-c M-r" #'diff-revert-and-kill-hunk
221 "C-c C-m a" #'diff-apply-buffer 222 "C-c C-m a" #'diff-apply-buffer
222 "C-c C-e" #'diff-ediff-patch 223 "C-c C-e" #'diff-ediff-patch
223 "C-c C-n" #'diff-restrict-view 224 "C-c C-n" #'diff-restrict-view
@@ -242,6 +243,8 @@ The default \"-b\" means to ignore whitespace-only changes,
242 :help "Apply the current hunk to the source file and go to the next"] 243 :help "Apply the current hunk to the source file and go to the next"]
243 ["Test applying hunk" diff-test-hunk 244 ["Test applying hunk" diff-test-hunk
244 :help "See whether it's possible to apply the current hunk"] 245 :help "See whether it's possible to apply the current hunk"]
246 ["Revert and kill hunk" diff-revert-and-kill-hunk
247 :help "Reverse-apply and then kill the current hunk."]
245 ["Apply all hunks" diff-apply-buffer 248 ["Apply all hunks" diff-apply-buffer
246 :help "Apply all hunks in the current diff buffer"] 249 :help "Apply all hunks in the current diff buffer"]
247 ["Apply diff with Ediff" diff-ediff-patch 250 ["Apply diff with Ediff" diff-ediff-patch
@@ -2050,24 +2053,52 @@ With a prefix argument, try to REVERSE the hunk."
2050 (diff-hunk-kill) 2053 (diff-hunk-kill)
2051 (diff-hunk-next))))) 2054 (diff-hunk-next)))))
2052 2055
2053(defun diff-apply-buffer () 2056(defcustom diff-ask-before-revert-and-kill-hunk t
2057 "If non-nil, `diff-revert-and-kill-hunk' will ask for confirmation."
2058 :type 'boolean)
2059
2060(defun diff-revert-and-kill-hunk ()
2061 "Reverse-apply and then kill the hunk at point. Save changed buffer.
2062
2063This command is useful in buffers generated by \\[vc-diff] and \\[vc-root-diff],
2064especially when preparing to commit the patch with \\[vc-next-action].
2065You can use \\<diff-mode-map>\\[diff-hunk-kill] to temporarily remove changes that you intend to
2066include in a separate commit or commits, and you can use this command
2067to permanently drop changes you didn't intend, or no longer want.
2068
2069This is a destructive operation, so by default, this command asks you to
2070confirm you really want to reverse-apply and kill the hunk. You can
2071customize `diff-ask-before-revert-and-kill-hunk' to change that."
2072 (interactive)
2073 (when (or (not diff-ask-before-revert-and-kill-hunk)
2074 (yes-or-no-p "Really reverse-apply and kill this hunk?"))
2075 (cl-destructuring-bind (beg end) (diff-bounds-of-hunk)
2076 (when (null (diff-apply-buffer beg end t))
2077 (diff-hunk-kill)))))
2078
2079(defun diff-apply-buffer (&optional beg end reverse)
2054 "Apply the diff in the entire diff buffer. 2080 "Apply the diff in the entire diff buffer.
2055When applying all hunks was successful, then save the changed buffers." 2081When applying all hunks was successful, then save the changed buffers.
2082When called from Lisp with optional arguments, restrict the application
2083to hunks lying between BEG and END, and reverse-apply when REVERSE is
2084non-nil. Returns nil if buffers were saved, or the number of failed
2085applications."
2056 (interactive) 2086 (interactive)
2057 (let ((buffer-edits nil) 2087 (let ((buffer-edits nil)
2058 (failures 0) 2088 (failures 0)
2059 (diff-refine nil)) 2089 (diff-refine nil))
2060 (save-excursion 2090 (save-excursion
2061 (goto-char (point-min)) 2091 (goto-char (or beg (point-min)))
2062 (diff-beginning-of-hunk t) 2092 (diff-beginning-of-hunk t)
2063 (while (pcase-let ((`(,buf ,line-offset ,pos ,_src ,dst ,switched) 2093 (while (pcase-let ((`(,buf ,line-offset ,pos ,_src ,dst ,switched)
2064 (diff-find-source-location nil nil))) 2094 (diff-find-source-location nil reverse)))
2065 (cond ((and line-offset (not switched)) 2095 (cond ((and line-offset (not switched))
2066 (push (cons pos dst) 2096 (push (cons pos dst)
2067 (alist-get buf buffer-edits))) 2097 (alist-get buf buffer-edits)))
2068 (t (setq failures (1+ failures)))) 2098 (t (setq failures (1+ failures))))
2069 (and (not (eq (prog1 (point) (ignore-errors (diff-hunk-next))) 2099 (and (not (eq (prog1 (point) (ignore-errors (diff-hunk-next)))
2070 (point))) 2100 (point)))
2101 (or (not end) (< (point) end))
2071 (looking-at-p diff-hunk-header-re))))) 2102 (looking-at-p diff-hunk-header-re)))))
2072 (cond ((zerop failures) 2103 (cond ((zerop failures)
2073 (dolist (buf-edits (reverse buffer-edits)) 2104 (dolist (buf-edits (reverse buffer-edits))
@@ -2080,11 +2111,13 @@ When applying all hunks was successful, then save the changed buffers."
2080 (delete-region (car pos) (cdr pos)) 2111 (delete-region (car pos) (cdr pos))
2081 (insert (car dst)))) 2112 (insert (car dst))))
2082 (save-buffer))) 2113 (save-buffer)))
2083 (message "Saved %d buffers" (length buffer-edits))) 2114 (message "Saved %d buffers" (length buffer-edits))
2115 nil)
2084 (t 2116 (t
2085 (message (ngettext "%d hunk failed; no buffers changed" 2117 (message (ngettext "%d hunk failed; no buffers changed"
2086 "%d hunks failed; no buffers changed" 2118 "%d hunks failed; no buffers changed"
2087 failures)))))) 2119 failures))
2120 failures))))
2088 2121
2089(defalias 'diff-mouse-goto-source #'diff-goto-source) 2122(defalias 'diff-mouse-goto-source #'diff-goto-source)
2090 2123