;; 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.
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)
(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
(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
(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))))))