-With a prefix argument, REVERSE the hunk.
-If OTHER-FILE is non-nil, patch the old file by default, and reverse the
- sense of `diff-jump-to-old-file-flag'.
-If DRY-RUN is non-nil, don't actually modify anything, just see whether
- it's possible to do so.
-If POPUP is non-nil, pop up the patched file in another window; if POPUP
- is `select' then select the new window too.
-If NOERROR is non-nil, then no error is signaled in the case where the hunk
- cannot be found in the source file (other errors may still be signaled).
-
-Return values are `t' if the hunk was sucessfully applied (or could be
-applied, in the case where DRY-RUN was non-nil), `reversed' if the hunk
-was applied backwards, or nil if the hunk couldn't be found and NOERROR
-was non-nil."
- (interactive (list current-prefix-arg nil nil t))
-
- (when other-file
- ;; OTHER-FILE inverts the sense of the hunk
- (setq reverse (not reverse)))
- (when diff-jump-to-old-file-flag
- ;; The global variable `diff-jump-to-old-file-flag' inverts the
- ;; sense of OTHER-FILE (in `diff-find-source-location')
- (setq reverse (not reverse)))
-
- (let* ((loc (diff-find-source-location other-file))
- (buf (find-file-noselect (car loc)))
- (patch-line (cadr loc))
- hunk-line-offset
- (hunk
- (let ((orig-point (point)))
- (save-excursion
- (diff-beginning-of-hunk)
- (setq hunk-line-offset (count-lines (point) orig-point))
- (unless (looking-at diff-hunk-header-re)
- (error "Malformed hunk"))
- (buffer-substring (point) (progn (diff-end-of-hunk) (point))))))
- (old (diff-hunk-text hunk reverse hunk-line-offset))
- (new (diff-hunk-text hunk (not reverse) hunk-line-offset))
- (pos
- (with-current-buffer buf (diff-find-text (car old) patch-line)))
- (reversed-pos
- (and (null pos)
- (with-current-buffer buf
- (diff-find-text (car new) patch-line)))))
-
- (when (and reversed-pos popup)
- ;; A reversed patch was detected, perhaps apply it in reverse
- ;; (this is only done in `interactive' mode, when POPUP is non-nil).
- (if (or dry-run
- (save-window-excursion
- (pop-to-buffer buf)
- (goto-char reversed-pos)
- (forward-line (cdr new))
- (if reverse
- (y-or-n-p
- "Hunk hasn't been applied yet, so can't reverse it; apply it now? ")
- (y-or-n-p "Hunk has already been applied; undo it? "))))
-
- ;; Set up things to reverse the diff
- (let ((swap new))
- (setq pos reversed-pos)
- (setq old new)
- (setq new swap))
-
- ;; The user has chosen not to apply the reversed hunk, but we
- ;; don't want to given an error message, so set things up so
- ;; nothing else gets done down below
- (message "(Nothing done)")
- (setq noerror t)))
-
- (if (null pos)
- ;; POS is nil, so we couldn't find the source text.
- (unless noerror
- (error "Can't find the text to patch"))
-
- (let ((reversed (if reversed-pos (not reverse) reverse)))
- (unless dry-run
- ;; Apply the hunk
- (with-current-buffer buf
- (goto-char pos)
- (delete-char (length (car old)))
- (insert (car new))))
+With a prefix argument, REVERSE the hunk."
+ (interactive "P")
+ (destructuring-bind (buf line-offset pos old new &optional switched)
+ (diff-find-source-location nil reverse)
+ (cond
+ ((null line-offset)
+ (error "Can't find the text to patch"))
+ ((and switched
+ ;; A reversed patch was detected, perhaps apply it in reverse.
+ (not (save-window-excursion
+ (pop-to-buffer buf)
+ (goto-char (+ pos (cdr old)))
+ (y-or-n-p
+ (if reverse
+ "Hunk hasn't been applied yet; apply it now? "
+ "Hunk has already been applied; undo it? ")))))
+ (message "(Nothing done)"))
+ (t
+ ;; Apply the hunk
+ (with-current-buffer buf
+ (goto-char pos)
+ (delete-char (length (car old)))
+ (insert (car new)))
+ ;; Display BUF in a window
+ (set-window-point (display-buffer buf) (+ pos (cdr new)))
+ (diff-hunk-status-msg line-offset (diff-xor switched reverse) nil)
+ (when diff-advance-after-apply-hunk
+ (diff-hunk-next))))))
+