Function: ediff-extract-diffs3
ediff-extract-diffs3 is a byte-compiled function defined in
ediff-diff.el.gz.
Signature
(ediff-extract-diffs3 DIFF-BUFFER WORD-MODE THREE-WAY-COMP &optional BOUNDS)
Source Code
;; Defined in /usr/src/emacs/lisp/vc/ediff-diff.el.gz
;; If WORD-MODE, construct vector of diffs using word numbers.
;; Else, use point values.
;; WORD-MODE also tells if we are in the word-mode or not.
;; If THREE-WAY-COMP, then it is a 3-way comparison. Else, it is merging
;; with ancestor, in which case buffer-C contents is identical to buffer-A/B,
;; contents (unless buffer-A is narrowed) depending on ediff-default-variant's
;; value.
;; BOUNDS specifies visibility bounds to use.
(defun ediff-extract-diffs3 (diff-buffer word-mode three-way-comp
&optional bounds)
(let ((A-buffer ediff-buffer-A)
(B-buffer ediff-buffer-B)
(C-buffer ediff-buffer-C)
(anc-buffer ediff-ancestor-buffer)
(a-prev 1) ; needed to set the first diff line correctly
(a-prev-pt nil)
(b-prev 1)
(b-prev-pt nil)
(c-prev 1)
(c-prev-pt nil)
(anc-prev 1)
diff-list shift-A shift-B shift-C
)
;; diff list contains word numbers or points, depending on word-mode
(setq diff-list (cons (if word-mode 'words 'points)
diff-list))
(if bounds
(setq shift-A
(ediff-overlay-start
(ediff-get-value-according-to-buffer-type 'A bounds))
shift-B
(ediff-overlay-start
(ediff-get-value-according-to-buffer-type 'B bounds))
shift-C
(if three-way-comp
(ediff-overlay-start
(ediff-get-value-according-to-buffer-type 'C bounds)))))
;; reset point in buffers A, B, C
(ediff-with-current-buffer A-buffer
(goto-char (if shift-A shift-A (point-min))))
(ediff-with-current-buffer B-buffer
(goto-char (if shift-B shift-B (point-min))))
(if three-way-comp
(ediff-with-current-buffer C-buffer
(goto-char (if shift-C shift-C (point-min)))))
(if (ediff-buffer-live-p anc-buffer)
(ediff-with-current-buffer anc-buffer
(goto-char (point-min))))
(ediff-with-current-buffer diff-buffer
(goto-char (point-min))
(while (re-search-forward ediff-match-diff3-line nil t)
;; leave point after matched line
(beginning-of-line 2)
(let ((agreement (buffer-substring (match-beginning 1) (match-end 1))))
;; if the files A and B are the same and not 3way-comparison,
;; ignore the difference
(if (or three-way-comp (not (string-equal agreement "3")))
(let* ((a-begin (car (ediff-get-diff3-group "1")))
(a-end (nth 1 (ediff-get-diff3-group "1")))
(b-begin (car (ediff-get-diff3-group "2")))
(b-end (nth 1 (ediff-get-diff3-group "2")))
(c-or-anc-begin (car (ediff-get-diff3-group "3")))
(c-or-anc-end (nth 1 (ediff-get-diff3-group "3")))
(state-of-merge
(cond ((string-equal agreement "1") 'prefer-A)
((string-equal agreement "2") 'prefer-B)
(t ediff-default-variant)))
(state-of-diff-merge
(if (memq state-of-merge '(default-A prefer-A)) 'B 'A))
(state-of-diff-comparison
(cond ((string-equal agreement "1") 'A)
((string-equal agreement "2") 'B)
((string-equal agreement "3") 'C)))
state-of-ancestor
c-begin c-end
a-begin-pt a-end-pt
b-begin-pt b-end-pt
c-begin-pt c-end-pt
anc-begin-pt anc-end-pt)
(setq state-of-ancestor
(= c-or-anc-begin c-or-anc-end))
(cond (three-way-comp
(setq c-begin c-or-anc-begin
c-end c-or-anc-end))
((eq ediff-default-variant 'default-B)
(setq c-begin b-begin
c-end b-end))
(t
(setq c-begin a-begin
c-end a-end)))
;; compute main diff vector
(if word-mode
;; make diff-list contain word numbers
(setq diff-list
(nconc diff-list
(list (vector
(- a-begin a-prev) (- a-end a-begin)
(- b-begin b-prev) (- b-end b-begin)
(- c-begin c-prev) (- c-end c-begin)
nil nil ; dummy ancestor
nil ; state of diff
nil ; state of merge
nil ; state of ancestor
)))
a-prev a-end
b-prev b-end
c-prev c-end)
;; else convert lines to points
(ediff-with-current-buffer A-buffer
(goto-char (or a-prev-pt shift-A (point-min)))
(forward-line (- a-begin a-prev))
(setq a-begin-pt (point))
(forward-line (- a-end a-begin))
(setq a-end-pt (point)
a-prev a-end
a-prev-pt a-end-pt))
(ediff-with-current-buffer B-buffer
(goto-char (or b-prev-pt shift-B (point-min)))
(forward-line (- b-begin b-prev))
(setq b-begin-pt (point))
(forward-line (- b-end b-begin))
(setq b-end-pt (point)
b-prev b-end
b-prev-pt b-end-pt))
(ediff-with-current-buffer C-buffer
(goto-char (or c-prev-pt shift-C (point-min)))
(forward-line (- c-begin c-prev))
(setq c-begin-pt (point))
(forward-line (- c-end c-begin))
(setq c-end-pt (point)
c-prev c-end
c-prev-pt c-end-pt))
(if (ediff-buffer-live-p anc-buffer)
(ediff-with-current-buffer anc-buffer
(forward-line (- c-or-anc-begin anc-prev))
(setq anc-begin-pt (point))
(forward-line (- c-or-anc-end c-or-anc-begin))
(setq anc-end-pt (point)
anc-prev c-or-anc-end)))
(setq diff-list
(nconc
diff-list
;; if comparing with ancestor, then there also is a
;; state-of-difference marker
(if three-way-comp
(list (vector
a-begin-pt a-end-pt
b-begin-pt b-end-pt
c-begin-pt c-end-pt
nil nil ; ancestor begin/end
state-of-diff-comparison
nil ; state of merge
nil ; state of ancestor
))
(list (vector a-begin-pt a-end-pt
b-begin-pt b-end-pt
c-begin-pt c-end-pt
anc-begin-pt anc-end-pt
state-of-diff-merge
state-of-merge
state-of-ancestor
)))
)))
))
))) ; end ediff-with-current-buffer
diff-list
))