changeset 31819:e5a0c7120611

(diff-hunk-text): Properly handle one-sided context diffs. (diff-apply-hunk): When done, advance to the next hunk.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Thu, 21 Sep 2000 16:52:23 +0000
parents 1e15c63f0711
children 28cd92291814
files lisp/diff-mode.el
diffstat 1 files changed, 76 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/diff-mode.el	Thu Sep 21 16:28:06 2000 +0000
+++ b/lisp/diff-mode.el	Thu Sep 21 16:52:23 2000 +0000
@@ -4,7 +4,7 @@
 
 ;; Author: Stefan Monnier <monnier@cs.yale.edu>
 ;; Keywords: patch diff
-;; Revision: $Id: diff-mode.el,v 1.20 2000/09/20 22:36:23 monnier Exp $
+;; Revision: $Id: diff-mode.el,v 1.21 2000/09/21 16:15:32 monnier Exp $
 
 ;; This file is part of GNU Emacs.
 
@@ -876,75 +876,80 @@
 HUNK, and instead of a string, a cons cell is returned whose car is the
 appropriate text, and whose cdr is the corresponding char-offset in that text."
   (with-temp-buffer
-     (insert hunk)
-     (goto-char (point-min))
-     (let ((src-pos nil)
-	   (dst-pos nil)
-	   (divider-pos nil)
-	   (num-pfx-chars 2))
-       ;; Set the following variables:
-       ;;  SRC-POS     buffer pos of the source part of the hunk or nil if none
-       ;;  DST-POS     buffer pos of the destination part of the hunk or nil
-       ;;  DIVIDER-POS buffer pos of any divider line separating the src & dst
-       ;;  NUM-PFX-CHARS  number of line-prefix characters used by this format"
-       (cond ((looking-at "^@@")
-	      ;; unified diff
-	      (setq num-pfx-chars 1)
-	      (forward-line 1)
-	      (setq src-pos (point) dst-pos (point)))
-	     ((looking-at "^\\*\\*")
-	      ;; context diff
-	      (forward-line 2)
-	      (setq src-pos (point))
-	      (re-search-forward "^--- " nil t)
-	      (forward-line 0)
-	      (setq divider-pos (point))
-	      (forward-line 1)
-	      (setq dst-pos (point)))
-	     ((looking-at "^[0-9]+a[0-9,]+$")
-	      ;; normal diff, insert
-	      (forward-line 1)
-	      (setq dst-pos (point)))
-	     ((looking-at "^[0-9,]+d[0-9]+$")
-	      ;; normal diff, delete
-	      (forward-line 1)
-	      (setq src-pos (point)))
-	     ((looking-at "^[0-9,]+c[0-9,]+$")
-	      ;; normal diff, change
-	      (forward-line 1)
-	      (setq src-pos (point))
-	      (re-search-forward "^---$" nil t)
-	      (forward-line 0)
-	      (setq divider-pos (point))
-	      (forward-line 1)
-	      (setq dst-pos (point)))
-	     (t
-	      (error "Unknown diff hunk type")))
-    (if (if destp (null dst-pos) (null src-pos))
-	;; Implied empty text
-	(if char-offset '("" . 0) "")
+    (insert hunk)
+    (goto-char (point-min))
+    (let ((src-pos nil)
+	  (dst-pos nil)
+	  (divider-pos nil)
+	  (num-pfx-chars 2))
+      ;; Set the following variables:
+      ;;  SRC-POS     buffer pos of the source part of the hunk or nil if none
+      ;;  DST-POS     buffer pos of the destination part of the hunk or nil
+      ;;  DIVIDER-POS buffer pos of any divider line separating the src & dst
+      ;;  NUM-PFX-CHARS  number of line-prefix characters used by this format"
+      (cond ((looking-at "^@@")
+	     ;; unified diff
+	     (setq num-pfx-chars 1)
+	     (forward-line 1)
+	     (setq src-pos (point) dst-pos (point)))
+	    ((looking-at "^\\*\\*")
+	     ;; context diff
+	     (forward-line 2)
+	     (setq src-pos (point))
+	     (re-search-forward "^--- " nil t)
+	     (forward-line 0)
+	     (setq divider-pos (point))
+	     (forward-line 1)
+	     (setq dst-pos (point)))
+	    ((looking-at "^[0-9]+a[0-9,]+$")
+	     ;; normal diff, insert
+	     (forward-line 1)
+	     (setq dst-pos (point)))
+	    ((looking-at "^[0-9,]+d[0-9]+$")
+	     ;; normal diff, delete
+	     (forward-line 1)
+	     (setq src-pos (point)))
+	    ((looking-at "^[0-9,]+c[0-9,]+$")
+	     ;; normal diff, change
+	     (forward-line 1)
+	     (setq src-pos (point))
+	     (re-search-forward "^---$" nil t)
+	     (forward-line 0)
+	     (setq divider-pos (point))
+	     (forward-line 1)
+	     (setq dst-pos (point)))
+	    (t
+	     (error "Unknown diff hunk type")))
 
-      (when char-offset (goto-char (+ (point-min) char-offset)))
+      (if (if destp (null dst-pos) (null src-pos))
+	  ;; Implied empty text
+	  (if char-offset '("" . 0) "")
+
+	;; For context diffs, either side can be empty, (if there's only
+	;; added or only removed text).  We should then use the other side.
+	(cond ((equal src-pos divider-pos) (setq src-pos dst-pos))
+	      ((equal dst-pos (point-max)) (setq dst-pos src-pos)))
+
+	(when char-offset (goto-char (+ (point-min) char-offset)))
 
-      ;; Get rid of anything except the desired text.
-      (save-excursion
-	;; Delete unused text region
-	(let ((keep (if destp dst-pos src-pos))
-	      (kill (or divider-pos (if destp src-pos dst-pos))))
-	  (when (and kill (> kill keep))
-	    (delete-region kill (point-max)))
-	  (delete-region (point-min) keep))
-	;; Remove line-prefix characters, and unneeded lines (unified diffs).
-	(let ((kill-char (if destp ?- ?+)))
-	  (goto-char (point-min))
-	  (while (not (eobp))
-	    (if (eq (char-after) kill-char)
-		(delete-region (point) (progn (forward-line 1) (point)))
-	      (delete-char num-pfx-chars)
-	      (forward-line 1)))))
+	;; Get rid of anything except the desired text.
+	(save-excursion
+	  ;; Delete unused text region
+	  (let ((keep (if destp dst-pos src-pos)))
+	    (when (and divider-pos (> divider-pos keep))
+	      (delete-region divider-pos (point-max)))
+	    (delete-region (point-min) keep))
+	  ;; Remove line-prefix characters, and unneeded lines (unified diffs).
+	  (let ((kill-char (if destp ?- ?+)))
+	    (goto-char (point-min))
+	    (while (not (eobp))
+	      (if (eq (char-after) kill-char)
+		  (delete-region (point) (progn (forward-line 1) (point)))
+		(delete-char num-pfx-chars)
+		(forward-line 1)))))
 
-      (let ((text (buffer-substring-no-properties (point-min) (point-max))))
-	(if char-offset (cons text (- (point) (point-min))) text))))))
+	(let ((text (buffer-substring-no-properties (point-min) (point-max))))
+	  (if char-offset (cons text (- (point) (point-min))) text))))))
 
 
 (defun diff-find-text (text)
@@ -1010,7 +1015,7 @@
 
 
 (defun diff-apply-hunk (&optional reverse)
-  "Apply the current hunk to the source file.
+  "Apply the current hunk to the source file and go to the next.
 By default, the new source file is patched, but if the variable
 `diff-jump-to-old-file-flag' is non-nil, then the old source file is
 patched instead (some commands, such as `diff-goto-source' can change
@@ -1034,7 +1039,8 @@
 		   (if reverse
 		       "Hunk hasn't been applied yet; apply it now? "
 		     "Hunk has already been applied; undo it? ")))))
-      (message "(Nothing done)"))
+      (message "(Nothing done)")
+      nil)
      (t
       (let ((reversed (diff-xor switched reverse)))
 	;; Apply the hunk
@@ -1046,6 +1052,7 @@
 	(let ((win (display-buffer buf)))
 	  (set-window-point win (+ pos (cdr new))))
 	(diff-hunk-status-msg line-offset reversed nil)
+	(diff-hunk-next)
 	(if reversed 'reversed t))))))