Function: diff-find-source-location

diff-find-source-location is a byte-compiled function defined in diff-mode.el.gz.

Signature

(diff-find-source-location &optional OTHER-FILE REVERSE NOPROMPT)

Documentation

Find current diff location within the source file.

OTHER-FILE, if non-nil, means to look at the diff's name and line
  numbers for the old file. Furthermore, use diff-vc-revisions
  if it's available. If diff-jump-to-old-file is non-nil, the
  sense of this parameter is reversed. If OTHER-FILE considered
  as a raw prefix argument has a numeric value bigger than 8,
  toggle diff-jump-to-old-file for the remainder of this Emacs
  session, i.e., set it to nil if it's non-nil, non-nil if it's nil.
REVERSE, if non-nil, switches the sense of SRC and DST (see below). NOPROMPT, if non-nil, means not to prompt the user. Return a list (BUF LINE-OFFSET (BEG . END) SRC DST SWITCHED). BUF is the buffer corresponding to the source file. LINE-OFFSET is the offset between the expected and actual positions
  of the text of the hunk or nil if the text was not found.
(BEG . END) is a pair indicating the position of the text in the buffer.
SRC and DST are the two variants of text as returned by diff-hunk-text.
  SRC is the variant that was found in the buffer.
SWITCHED is non-nil if the patch is already applied.

Source Code

;; Defined in /usr/src/emacs/lisp/vc/diff-mode.el.gz
(defun diff-find-source-location (&optional other-file reverse noprompt)
  "Find current diff location within the source file.
OTHER-FILE, if non-nil, means to look at the diff's name and line
  numbers for the old file.  Furthermore, use `diff-vc-revisions'
  if it's available.  If `diff-jump-to-old-file' is non-nil, the
  sense of this parameter is reversed.  If OTHER-FILE considered
  as a raw prefix argument has a numeric value bigger than 8,
  toggle `diff-jump-to-old-file' for the remainder of this Emacs
  session, i.e., set it to nil if it's non-nil, non-nil if it's nil.
REVERSE, if non-nil, switches the sense of SRC and DST (see below).
NOPROMPT, if non-nil, means not to prompt the user.
Return a list (BUF LINE-OFFSET (BEG . END) SRC DST SWITCHED).
BUF is the buffer corresponding to the source file.
LINE-OFFSET is the offset between the expected and actual positions
  of the text of the hunk or nil if the text was not found.
\(BEG . END) is a pair indicating the position of the text in the buffer.
SRC and DST are the two variants of text as returned by `diff-hunk-text'.
  SRC is the variant that was found in the buffer.
SWITCHED is non-nil if the patch is already applied."
  (save-excursion
    (let* ((other (xor other-file diff-jump-to-old-file))
	   (char-offset (- (point) (diff-beginning-of-hunk t)))
           ;; Check that the hunk is well-formed.  Otherwise diff-mode and
           ;; the user may disagree on what constitutes the hunk
           ;; (e.g. because an empty line truncates the hunk mid-course),
           ;; leading to potentially nasty surprises for the user.
	   ;;
	   ;; Suppress check when NOPROMPT is non-nil (Bug#3033).
           (_ (unless noprompt (diff-sanity-check-hunk)))
	   (hunk (buffer-substring
                  (point) (save-excursion (diff-end-of-hunk) (point))))
	   (old (diff-hunk-text hunk reverse char-offset))
	   (new (diff-hunk-text hunk (not reverse) char-offset))
	   ;; Find the location specification.
	   (line (if (not (looking-at "\\(?:\\*\\{15\\}.*\n\\)?[-@* ]*\\([0-9,]+\\)\\([ acd+]+\\([0-9,]+\\)\\)?"))
		     (error "Can't find the hunk header")
		   (if other (match-string 1)
		     (if (match-end 3) (match-string 3)
		       (unless (re-search-forward
                                diff-context-mid-hunk-header-re nil t)
			 (error "Can't find the hunk separator"))
		       (match-string 1)))))
	   (file (or (diff-find-file-name other noprompt)
                     (error "Can't find the file")))
	   (revision (and other diff-vc-backend
                          (if reverse (nth 1 diff-vc-revisions)
                            (or (nth 0 diff-vc-revisions)
                                ;; When diff shows changes in working revision
                                (vc-working-revision file)))))
	   (buf (if revision
                    (let ((vc-find-revision-no-save t))
                      (vc-find-revision (expand-file-name file) revision diff-vc-backend))
                  ;; NOPROMPT is only non-nil when called from
                  ;; `which-function-mode', so avoid "File x changed
                  ;; on disk. Reread from disk?" warnings.
                  (find-file-noselect file noprompt))))
      ;; Update the user preference if he so wished.
      (when (> (prefix-numeric-value other-file) 8)
	(setq diff-jump-to-old-file other))
      (with-current-buffer buf
        (goto-char (point-min)) (forward-line (1- (string-to-number line)))
	(let* ((orig-pos (point))
	       (switched nil)
	       (maybe-old (diff-find-text (car old)))
	       (maybe-new (diff-find-text (car new)))
	       (pos (or (and maybe-new maybe-old (null reverse) (setq switched t) maybe-new)
			maybe-old
			(progn (setq switched t) maybe-new)
			(progn (setq switched nil)
			       (condition-case nil
				   (diff-find-approx-text (car old))
				 (invalid-regexp nil)))	;Regex too big.
			(progn (setq switched t)
			       (condition-case nil
				   (diff-find-approx-text (car new))
				 (invalid-regexp nil)))	;Regex too big.
			(progn (setq switched nil) nil))))
	  (nconc
	   (list buf)
	   (if pos
	       (list (count-lines orig-pos (car pos)) pos)
	     (list nil (cons orig-pos (+ orig-pos (length (car old))))))
	   (if switched (list new old t) (list old new))))))))