unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Tino Calancha <tino.calancha@gmail.com>
To: 25571@debbugs.gnu.org
Subject: bug#25571: 24.5; Check if there are hunks before kill or refine a hunk
Date: Sun, 29 Jan 2017 20:37:37 +0900 (JST)	[thread overview]
Message-ID: <alpine.DEB.2.20.1701292037160.6886@calancha-pc> (raw)


emacs -Q:
; Put following content in a buffer in diff-mode:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; START
diff --git a/a b/a
index 184cbf6..d2d9a24 100644
--- a/a
+++ b/a
@@ -1,2 +1,2 @@
-I have a foo in my bar.
+I have a qux in my bar.
  Me too.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END
From ed6a10f980bd1eec73982582db7599f936fa5315 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Sun, 29 Jan 2017 20:29:47 +0900
Subject: [PATCH] Check if there are hunks before kill or refine a hunk

* lisp/vc/diff-mode.el (diff--some-hunks-p): New predicate.
(diff-hunk-kill, diff-file-kill, diff-refine-hunk): Use it (Bug#25571).
---
  lisp/vc/diff-mode.el | 156 +++++++++++++++++++++++++++------------------------
  1 file changed, 83 insertions(+), 73 deletions(-)

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index e609ca9f94..4ad03be7f0 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -647,28 +647,35 @@ diff-restrict-view
  	 (if arg (diff-bounds-of-file) (diff-bounds-of-hunk)))
    (set (make-local-variable 'diff-narrowed-to) (if arg 'file 'hunk)))

+(defun diff--some-hunks-p ()
+  (save-excursion
+    (goto-char (point-min))
+    (re-search-forward diff-hunk-header-re nil t)))
+
  (defun diff-hunk-kill ()
    "Kill the hunk at point."
    (interactive)
-  (let* ((hunk-bounds (diff-bounds-of-hunk))
-	 (file-bounds (ignore-errors (diff-bounds-of-file)))
-	 ;; If the current hunk is the only one for its file, kill the
-	 ;; file header too.
-	 (bounds (if (and file-bounds
-			  (progn (goto-char (car file-bounds))
-				 (= (progn (diff-hunk-next) (point))
-				    (car hunk-bounds)))
-			  (progn (goto-char (cadr hunk-bounds))
-				 ;; bzr puts a newline after the last hunk.
-				 (while (looking-at "^\n")
-				   (forward-char 1))
-				 (= (point) (cadr file-bounds))))
-		     file-bounds
-		   hunk-bounds))
-	 (inhibit-read-only t))
-    (apply 'kill-region bounds)
-    (goto-char (car bounds))
-    (diff-beginning-of-hunk t)))
+  (if (not (diff--some-hunks-p))
+      (error "No more hunks")
+    (let* ((hunk-bounds (diff-bounds-of-hunk))
+           (file-bounds (ignore-errors (diff-bounds-of-file)))
+           ;; If the current hunk is the only one for its file, kill the
+           ;; file header too.
+           (bounds (if (and file-bounds
+                            (progn (goto-char (car file-bounds))
+                                   (= (progn (diff-hunk-next) (point))
+                                      (car hunk-bounds)))
+                            (progn (goto-char (cadr hunk-bounds))
+                                   ;; bzr puts a newline after the last hunk.
+                                   (while (looking-at "^\n")
+                                     (forward-char 1))
+                                   (= (point) (cadr file-bounds))))
+                       file-bounds
+                     hunk-bounds))
+           (inhibit-read-only t))
+      (apply 'kill-region bounds)
+      (goto-char (car bounds))
+      (diff-beginning-of-hunk t))))

  (defun diff-beginning-of-file-and-junk ()
    "Go to the beginning of file-related diff-info.
@@ -720,9 +727,11 @@ diff-beginning-of-file-and-junk
  (defun diff-file-kill ()
    "Kill current file's hunks."
    (interactive)
-  (let ((inhibit-read-only t))
-    (apply 'kill-region (diff-bounds-of-file)))
-  (diff-beginning-of-hunk t))
+  (if (not (diff--some-hunks-p))
+      (error "No more hunks")
+    (let ((inhibit-read-only t))
+      (apply 'kill-region (diff-bounds-of-file)))
+    (diff-beginning-of-hunk t)))

  (defun diff-kill-junk ()
    "Kill spurious empty diffs."
@@ -2000,57 +2009,58 @@ diff-refine-hunk
    "Highlight changes of hunk at point at a finer granularity."
    (interactive)
    (require 'smerge-mode)
-  (save-excursion
-    (diff-beginning-of-hunk t)
-    (let* ((start (point))
-           (style (diff-hunk-style))    ;Skips the hunk header as well.
-           (beg (point))
-           (props-c '((diff-mode . fine) (face diff-refine-changed)))
-           (props-r '((diff-mode . fine) (face diff-refine-removed)))
-           (props-a '((diff-mode . fine) (face diff-refine-added)))
-           ;; Be careful to go back to `start' so diff-end-of-hunk gets
-           ;; to read the hunk header's line info.
-           (end (progn (goto-char start) (diff-end-of-hunk) (point))))
-
-      (remove-overlays beg end 'diff-mode 'fine)
-
-      (goto-char beg)
-      (pcase style
-        (`unified
-         (while (re-search-forward "^-" end t)
-           (let ((beg-del (progn (beginning-of-line) (point)))
-                 beg-add end-add)
-             (when (and (diff--forward-while-leading-char ?- end)
-                        ;; Allow for "\ No newline at end of file".
-                        (progn (diff--forward-while-leading-char ?\\ end)
-                               (setq beg-add (point)))
-                        (diff--forward-while-leading-char ?+ end)
-                        (progn (diff--forward-while-leading-char ?\\ end)
-                               (setq end-add (point))))
-               (smerge-refine-subst beg-del beg-add beg-add end-add
-                                    nil 'diff-refine-preproc props-r props-a)))))
-        (`context
-         (let* ((middle (save-excursion (re-search-forward "^---")))
-                (other middle))
-           (while (re-search-forward "^\\(?:!.*\n\\)+" middle t)
-             (smerge-refine-subst (match-beginning 0) (match-end 0)
-                                  (save-excursion
-                                    (goto-char other)
-                                    (re-search-forward "^\\(?:!.*\n\\)+" end)
-                                    (setq other (match-end 0))
-                                    (match-beginning 0))
-                                  other
-                                  (if diff-use-changed-face props-c)
-                                  'diff-refine-preproc
-                                  (unless diff-use-changed-face props-r)
-                                  (unless diff-use-changed-face props-a)))))
-        (_ ;; Normal diffs.
-         (let ((beg1 (1+ (point))))
-           (when (re-search-forward "^---.*\n" end t)
-             ;; It's a combined add&remove, so there's something to do.
-             (smerge-refine-subst beg1 (match-beginning 0)
-                                  (match-end 0) end
-                                  nil 'diff-refine-preproc props-r props-a))))))))
+  (when (diff--some-hunks-p)
+    (save-excursion
+      (diff-beginning-of-hunk t)
+      (let* ((start (point))
+             (style (diff-hunk-style))    ;Skips the hunk header as well.
+             (beg (point))
+             (props-c '((diff-mode . fine) (face diff-refine-changed)))
+             (props-r '((diff-mode . fine) (face diff-refine-removed)))
+             (props-a '((diff-mode . fine) (face diff-refine-added)))
+             ;; Be careful to go back to `start' so diff-end-of-hunk gets
+             ;; to read the hunk header's line info.
+             (end (progn (goto-char start) (diff-end-of-hunk) (point))))
+
+        (remove-overlays beg end 'diff-mode 'fine)
+
+        (goto-char beg)
+        (pcase style
+          (`unified
+           (while (re-search-forward "^-" end t)
+             (let ((beg-del (progn (beginning-of-line) (point)))
+                   beg-add end-add)
+               (when (and (diff--forward-while-leading-char ?- end)
+                          ;; Allow for "\ No newline at end of file".
+                          (progn (diff--forward-while-leading-char ?\\ end)
+                                 (setq beg-add (point)))
+                          (diff--forward-while-leading-char ?+ end)
+                          (progn (diff--forward-while-leading-char ?\\ end)
+                                 (setq end-add (point))))
+                 (smerge-refine-subst beg-del beg-add beg-add end-add
+                                      nil 'diff-refine-preproc props-r props-a)))))
+          (`context
+           (let* ((middle (save-excursion (re-search-forward "^---")))
+                  (other middle))
+             (while (re-search-forward "^\\(?:!.*\n\\)+" middle t)
+               (smerge-refine-subst (match-beginning 0) (match-end 0)
+                                    (save-excursion
+                                      (goto-char other)
+                                      (re-search-forward "^\\(?:!.*\n\\)+" end)
+                                      (setq other (match-end 0))
+                                      (match-beginning 0))
+                                    other
+                                    (if diff-use-changed-face props-c)
+                                    'diff-refine-preproc
+                                    (unless diff-use-changed-face props-r)
+                                    (unless diff-use-changed-face props-a)))))
+          (_ ;; Normal diffs.
+           (let ((beg1 (1+ (point))))
+             (when (re-search-forward "^---.*\n" end t)
+               ;; It's a combined add&remove, so there's something to do.
+               (smerge-refine-subst beg1 (match-beginning 0)
+                                    (match-end 0) end
+                                    nil 'diff-refine-preproc props-r props-a)))))))))

  (defun diff-undo (&optional arg)
    "Perform `undo', ignoring the buffer's read-only status."
-- 
2.11.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.6)
  of 2017-01-29
Repository revision: 0073223c23749ffd6bd3f882bc30a82cc37efd2a






             reply	other threads:[~2017-01-29 11:37 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-29 11:37 Tino Calancha [this message]
2017-01-29 11:46 ` bug#25571: 24.5; Check if there are hunks before kill or refine a hunk Tino Calancha
2017-02-02 13:34   ` Tino Calancha

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=alpine.DEB.2.20.1701292037160.6886@calancha-pc \
    --to=tino.calancha@gmail.com \
    --cc=25571@debbugs.gnu.org \
    /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).