# HG changeset patch # User Stefan Monnier # Date 969555143 0 # Node ID e5a0c71206119eb7934f820786eaa711fcfabf76 # Parent 1e15c63f0711f9b2328efa3001c1f706481e1470 (diff-hunk-text): Properly handle one-sided context diffs. (diff-apply-hunk): When done, advance to the next hunk. diff -r 1e15c63f0711 -r e5a0c7120611 lisp/diff-mode.el --- 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 ;; 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))))))