From: Stefan Monnier Date: Thu, 21 Sep 2000 16:52:30 +0000 (+0000) Subject: (diff-hunk-text): Properly handle one-sided context diffs. X-Git-Tag: emacs-pretest-21.0.90~1442 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=6e4e8a3b59a7f81c0611bebf08e38f98b4d3f5a6;p=emacs.git (diff-hunk-text): Properly handle one-sided context diffs. (diff-apply-hunk): When done, advance to the next hunk. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 608bdec8adb..7f3d49ba90d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,16 @@ +2000-09-21 Stefan Monnier + + * diff-mode.el (diff-file-header-face): Reset to its previous value. + (diff-hunk-text): Correctly use offsets rather than buffer-positions. + (diff-xor): New function. + (diff-find-source-location): Use it. Fix a stupid name clash. + (diff-hunk-status-msg): New function. + (diff-apply-hunk): Drop args OTHER-FILE, DRY-RUN, POPUP and NOERROR. + (diff-test-hunk): Use diff-find-source-location. + (diff-goto-source): Favor the `reverse'. + (diff-hunk-text): Properly handle one-sided context diffs. + (diff-apply-hunk): When done, advance to the next hunk. + 2000-09-21 Gerd Moellmann * add-log.el (change-log-date-face, change-log-name-face) diff --git a/lisp/diff-mode.el b/lisp/diff-mode.el index 17ef4697faf..1d00f696452 100644 --- a/lisp/diff-mode.el +++ b/lisp/diff-mode.el @@ -4,7 +4,7 @@ ;; Author: Stefan Monnier ;; 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 @@ If CHAR-OFFSET is non-nil, it should be a char-offset in 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) "") - - (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))))) - - (let ((text (buffer-substring-no-properties (point-min) (point-max)))) - (if char-offset (cons text (- (point) (point-min))) text)))))) + (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) "") + + ;; 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))) + (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)))))) (defun diff-find-text (text) @@ -1010,7 +1015,7 @@ If TEXT isn't found, nil is returned." (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 @@ hunk was applied backwards and nil if the hunk wasn't applied." (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 @@ hunk was applied backwards and nil if the hunk wasn't applied." (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))))))