-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
- (save-excursion
- (diff-beginning-of-hunk)
- (unless (looking-at diff-hunk-header-re)
- (error "Malformed hunk"))
- (buffer-substring (point) (progn (diff-end-of-hunk) (point)))))
- (src (diff-hunk-text hunk reverse))
- (dst (diff-hunk-text hunk (not reverse)))
- (pos
- (with-current-buffer buf (diff-find-text src patch-line)))
- (reversed-pos
- (and (null pos)
- (with-current-buffer buf (diff-find-text dst 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)
- (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 dst))
- (setq pos reversed-pos)
- (setq src dst)
- (setq dst 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 src))
- (insert dst)))
-
- (when popup
- ;; Show a message describing what was done
- (let ((real-line
- (1+ (with-current-buffer buf (count-lines (point-min) pos))))
- (msg
- (if dry-run
- (if reversed "already applied" "not yet applied")
- (if reversed "undone" "applied"))))
- (cond ((= real-line patch-line)
- (message "Hunk %s" msg))
- ((= real-line (1+ patch-line))
- (message "Hunk %s at offset 1 line" msg))
- (t
- (message "Hunk %s at offset %d lines"
- msg
- (- real-line patch-line)))))
-
- ;; Display BUF in a window, and maybe select it
- (let ((win (display-buffer buf)))
- (set-window-point win pos)
- (when (eq popup 'select)
- (select-window win))))
-
- ;; Return an appropriate indicator of success
- (if reversed 'reversed t)))))
-
-
+With a prefix argument, REVERSE the hunk."
+ (interactive "P")
+ (destructuring-bind (buf line-offset pos old new &optional switched)
+ ;; If REVERSE go to the new file, otherwise go to the old.
+ (diff-find-source-location (not reverse) 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 (+ (car 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 (car pos))
+ (delete-region (car pos) (cdr pos))
+ (insert (car new)))
+ ;; Display BUF in a window
+ (set-window-point (display-buffer buf) (+ (car pos) (cdr new)))
+ (diff-hunk-status-msg line-offset (diff-xor switched reverse) nil)
+ (when diff-advance-after-apply-hunk
+ (diff-hunk-next))))))
+
+