unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Sean Whitton <spwhitton@spwhitton.name>
To: Juri Linkov <juri@linkov.net>, dgutov@yandex.ru
Cc: 73407@debbugs.gnu.org
Subject: bug#73407: 31.0.50; Add diff-discard-hunk
Date: Tue, 24 Sep 2024 09:40:30 +0100	[thread overview]
Message-ID: <87y13hmold.fsf@zephyr.silentflame.com> (raw)
In-Reply-To: <865xqleexg.fsf@mail.linkov.net> (Juri Linkov's message of "Tue,  24 Sep 2024 09:36:27 +0300")

[-- Attachment #1: Type: text/plain, Size: 225 bytes --]

Hello,

Thank you both for looking.  Here is a revised patch based on Juri's
ideas about implementation, and also adding a y/n confirmation, since
this operation is destructive.

Let me know what you think!

-- 
Sean Whitton

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v2-0001-New-command-diff-discard-hunk.patch --]
[-- Type: text/x-patch, Size: 5926 bytes --]

From 2eccebb6159e6c384e1cb7a543f259d2146d8b81 Mon Sep 17 00:00:00 2001
From: Sean Whitton <spwhitton@spwhitton.name>
Date: Tue, 24 Sep 2024 09:38:43 +0100
Subject: [PATCH v2] New command diff-discard-hunk

* lisp/vc/diff-mode.el (diff-discard-hunk): New command (bug#73407).
(diff-apply-buffer): New optional BEG and END arguments.  Return
nil if buffers were saved, or the number of failed applications.
(diff-mode-map): Bind diff-discard-hunk to C-c C-k.
(diff-mode-menu): New entry "Discard hunk".
* doc/emacs/files.texi (Diff Mode):
* etc/NEWS: Document the new command.
---
 doc/emacs/files.texi | 11 +++++++++++
 etc/NEWS             |  5 +++++
 lisp/vc/diff-mode.el | 40 +++++++++++++++++++++++++++++++++++-----
 3 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi
index 709cb0910e6..04ecfabc1ee 100644
--- a/doc/emacs/files.texi
+++ b/doc/emacs/files.texi
@@ -1682,6 +1682,17 @@ Diff Mode
 version.  If @code{diff-jump-to-old-file} is non-@code{nil}, apply the
 hunk to the ``old'' version of the file instead.
 
+@findex diff-discard-hunk
+@item C-c C-k
+Reverse-apply this hunk to the target file, and then kill it
+(@code{diff-discard-hunk}).  Unless the buffer visiting the target file
+was already modified, save it.
+
+This command is useful in buffers generated by @w{@kbd{C-x v =}} and
+@w{@kbd{C-x v D}} (@pxref{Old Revisions}).  You can use this command to
+remove hunks you never intend to commit, such as temporary debug prints,
+and the like.
+
 @findex diff-apply-buffer
 @item C-c @key{RET} a
 Apply all the hunks in the buffer (@code{diff-apply-buffer}).  If the
diff --git a/etc/NEWS b/etc/NEWS
index c1a0524c8ba..3edd827d15c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -341,6 +341,11 @@ according to diffs in the current buffer, but without applying the diffs
 to the original text.  If the selected range extends a hunk, the
 command attempts to look up and copy the text in-between the hunks.
 
++++
+*** New command 'diff-discard-hunk' bound to C-c C-k.
+This command reverse-applies the hunk at point, and then kills it.
+This is useful in buffers generated C-x v = and C-x v D.
+
 ** php-ts-mode
 
 ---
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 4810b9ce01c..a48ba8e717a 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -218,6 +218,7 @@ diff-mode-map
   "C-x 4 A" #'diff-add-change-log-entries-other-window
   ;; Misc operations.
   "C-c C-a" #'diff-apply-hunk
+  "C-c C-k" #'diff-discard-hunk
   "C-c C-m a" #'diff-apply-buffer
   "C-c C-e" #'diff-ediff-patch
   "C-c C-n" #'diff-restrict-view
@@ -242,6 +243,8 @@ diff-mode-menu
      :help "Apply the current hunk to the source file and go to the next"]
     ["Test applying hunk"	diff-test-hunk
      :help "See whether it's possible to apply the current hunk"]
+    ["Discard hunk"             diff-discard-hunk
+     :help "Reverse-apply and then kill the current hunk."]
     ["Apply all hunks"		diff-apply-buffer
      :help "Apply all hunks in the current diff buffer"]
     ["Apply diff with Ediff"	diff-ediff-patch
@@ -2050,15 +2053,39 @@ diff-kill-applied-hunks
           (diff-hunk-kill)
         (diff-hunk-next)))))
 
-(defun diff-apply-buffer ()
+(defun diff-discard-hunk ()
+  "Reverse-apply and then kill the hunk at point.  Save changed buffer.
+
+This command is useful in buffers generated by \\[vc-diff] and \\[vc-root-diff].
+You can use `diff-hunk-kill' to remove hunks you intend to commit later.
+You can use this command to remove hunks you never intend to commit,
+such as temporary debug prints, and the like."
+  (interactive)
+  (when (yes-or-no-p "Discard this hunk?")
+    (cl-destructuring-bind (beg end) (diff-bounds-of-hunk)
+      (diff-reverse-direction beg end)
+      (condition-case ret
+          (diff-apply-buffer beg end)
+        ;; Reversing the hunk is an implementation detail, so ensure the
+        ;; user never sees it.
+        (error (diff-reverse-direction beg end)
+               (signal (car ret) (cdr ret)))
+        (:success (if ret
+                      (diff-reverse-direction beg end)
+                    (diff-hunk-kill)))))))
+
+(defun diff-apply-buffer (&optional beg end)
   "Apply the diff in the entire diff buffer.
-When applying all hunks was successful, then save the changed buffers."
+When applying all hunks was successful, then save the changed buffers.
+When called from Lisp with optional arguments, restrict the application
+to hunks lying between BEG and END.  Returns nil if buffers were saved,
+or the number of failed applications."
   (interactive)
   (let ((buffer-edits nil)
         (failures 0)
         (diff-refine nil))
     (save-excursion
-      (goto-char (point-min))
+      (goto-char (or beg (point-min)))
       (diff-beginning-of-hunk t)
       (while (pcase-let ((`(,buf ,line-offset ,pos ,_src ,dst ,switched)
                           (diff-find-source-location nil nil)))
@@ -2068,6 +2095,7 @@ diff-apply-buffer
                      (t (setq failures (1+ failures))))
                (and (not (eq (prog1 (point) (ignore-errors (diff-hunk-next)))
                              (point)))
+                    (or (not end) (< (point) end))
                     (looking-at-p diff-hunk-header-re)))))
     (cond ((zerop failures)
            (dolist (buf-edits (reverse buffer-edits))
@@ -2080,9 +2108,11 @@ diff-apply-buffer
                    (delete-region (car pos) (cdr pos))
                    (insert (car dst))))
                (save-buffer)))
-           (message "Saved %d buffers" (length buffer-edits)))
+           (message "Saved %d buffers" (length buffer-edits))
+           nil)
           (t
-           (message "%d hunks failed; no buffers changed" failures)))))
+           (message "%d hunks failed; no buffers changed" failures)
+           failures))))
 
 (defalias 'diff-mouse-goto-source #'diff-goto-source)
 
-- 
2.39.5


  parent reply	other threads:[~2024-09-24  8:40 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-21 10:19 bug#73407: 31.0.50; Add diff-discard-hunk Sean Whitton
2024-09-23 22:52 ` Dmitry Gutov
2024-09-24  7:53   ` Sean Whitton
2024-09-24 12:27     ` Dmitry Gutov
2024-09-24 15:48       ` Sean Whitton
2024-09-24  6:36 ` Juri Linkov
2024-09-24  8:07   ` Sean Whitton
2024-09-24  8:40   ` Sean Whitton [this message]
2024-09-24  8:42     ` Sean Whitton
2024-09-24 12:22       ` Dmitry Gutov
2024-09-24 12:21     ` Eli Zaretskii
2024-09-24 12:23       ` Dmitry Gutov
2024-09-24 14:33         ` Óscar Fuentes
2024-09-24 15:43       ` bug#73407: [PATCH v4] " Sean Whitton
2024-09-24 16:59         ` Juri Linkov
2024-09-24 17:56           ` Sean Whitton
2024-09-24 18:07           ` Eli Zaretskii
2024-09-25  6:36             ` Sean Whitton
2024-09-25 12:17               ` Eli Zaretskii
2024-09-25 19:33                 ` Sean Whitton
2024-09-24 12:20   ` Dmitry Gutov
2024-09-26 10:52 ` bug#73407: 31.0.50; Add diff-revert-and-kill-hunk Sean Whitton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y13hmold.fsf@zephyr.silentflame.com \
    --to=spwhitton@spwhitton.name \
    --cc=73407@debbugs.gnu.org \
    --cc=dgutov@yandex.ru \
    --cc=juri@linkov.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).