Commit 6e4e8a3b authored by Stefan Monnier's avatar Stefan Monnier

(diff-hunk-text): Properly handle one-sided context diffs.

(diff-apply-hunk): When done, advance to the next hunk.
parent 5768681d
2000-09-21 Stefan Monnier <monnier@cs.yale.edu>
* 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 <gerd@gnu.org>
* add-log.el (change-log-date-face, change-log-name-face)
......
......@@ -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 @@ 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))))))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment