1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-25 10:47:00 +00:00

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

(diff-apply-hunk): When done, advance to the next hunk.
This commit is contained in:
Stefan Monnier 2000-09-21 16:52:30 +00:00
parent 5768681d58
commit 6e4e8a3b59
2 changed files with 89 additions and 69 deletions

View File

@ -1,3 +1,16 @@
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)

View File

@ -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) "")
(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) "")
;; 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)))))
;; 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)))
(let ((text (buffer-substring-no-properties (point-min) (point-max))))
(if char-offset (cons text (- (point) (point-min))) text))))))
(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))))))