Function: ediff-make-fine-diffs

ediff-make-fine-diffs is a byte-compiled function defined in ediff-diff.el.gz.

Signature

(ediff-make-fine-diffs &optional N FLAG)

Source Code

;; Defined in /usr/src/emacs/lisp/vc/ediff-diff.el.gz
;; `n' is the diff region to work on.  Default is ediff-current-difference.
;; if `flag' is 'noforce then make fine-diffs only if this region's fine
;; diffs have not been computed before.
;; if `flag' is 'skip then don't compute fine diffs for this region.
(defun ediff-make-fine-diffs (&optional n flag)
  (or n  (setq n ediff-current-difference))

  (if (< ediff-number-of-differences 1)
      (error ediff-NO-DIFFERENCES))

  (if ediff-word-mode
      (setq flag 'skip
	    ediff-auto-refine 'nix))

  (or (< n 0)
      (>= n ediff-number-of-differences)
      ;; n is within the range
      (let ((tmp-buffer (get-buffer-create ediff-tmp-buffer))
	    (file-A ediff-temp-file-A)
	    (file-B ediff-temp-file-B)
	    (file-C ediff-temp-file-C)
	    (empty-A (ediff-empty-diff-region-p n 'A))
	    (empty-B (ediff-empty-diff-region-p n 'B))
	    (empty-C (ediff-empty-diff-region-p n 'C))
	    (whitespace-A (ediff-whitespace-diff-region-p n 'A))
	    (whitespace-B (ediff-whitespace-diff-region-p n 'B))
	    (whitespace-C (ediff-whitespace-diff-region-p n 'C))
	    cumulative-fine-diff-length)

	(cond ;; If one of the regions is empty (or 2 in 3way comparison)
	      ;; then don't refine.
	      ;; If the region happens to be entirely whitespace or empty then
	      ;; mark as such.
	      ((> (length (delq nil (list empty-A empty-B empty-C))) 1)
	       (if (and (ediff-looks-like-combined-merge n)
			ediff-merge-job)
		   (ediff-set-fine-overlays-in-one-buffer 'C nil n))
	       (if ediff-3way-comparison-job
		   (ediff-message-if-verbose
		    "Region %d is empty in all buffers but %S"
		    (1+ n)
		    (cond ((not empty-A) 'A)
			  ((not empty-B) 'B)
			  ((not empty-C) 'C)))
		 (ediff-message-if-verbose
		  "Region %d in buffer %S is empty"
		  (1+ n)
		  (cond (empty-A 'A)
			(empty-B 'B)
			(empty-C 'C)))
		 )
	       ;; if all regions happen to be whitespace
	       (if (and whitespace-A whitespace-B whitespace-C)
		   ;; mark as space only
		   (ediff-mark-diff-as-space-only n t)
		 ;; if some regions are white and others don't, then mark as
		 ;; non-white-space-only
		 (ediff-mark-diff-as-space-only n nil)))

	      ;; don't compute fine diffs if diff vector exists
	      ((and (eq flag 'noforce) (ediff-get-fine-diff-vector n 'A))
	       (if (ediff-no-fine-diffs-p n)
		   (message
		    "Only white-space differences in region %d %s"
		    (1+ n)
		    (cond ((eq (ediff-no-fine-diffs-p n) 'A)
			   "in buffers B & C")
			  ((eq (ediff-no-fine-diffs-p n) 'B)
			   "in buffers A & C")
			  ((eq (ediff-no-fine-diffs-p n) 'C)
			   "in buffers A & B")
			  (t "")))))
	      ;; don't compute fine diffs for this region
	      ((eq flag 'skip)
	       (or (ediff-get-fine-diff-vector n 'A)
		   (memq ediff-auto-refine '(off nix))
		   (ediff-message-if-verbose
		    "Region %d exceeds the auto-refinement limit. Type `%s' to refine"
		    (1+ n)
		    (substitute-command-keys
		     "\\[ediff-make-or-kill-fine-diffs]")
		    )))
	      (t
	       ;; recompute fine diffs
	       (ediff-wordify
		(ediff-get-diff-posn 'A 'beg n)
		(ediff-get-diff-posn 'A 'end n)
		ediff-buffer-A
		tmp-buffer
		ediff-control-buffer)
	       (setq file-A
		     (ediff-make-temp-file tmp-buffer "fineDiffA" file-A))

	       (ediff-wordify
		(ediff-get-diff-posn 'B 'beg n)
		(ediff-get-diff-posn 'B 'end n)
		ediff-buffer-B
		tmp-buffer
		ediff-control-buffer)
	       (setq file-B
		     (ediff-make-temp-file tmp-buffer "fineDiffB" file-B))

	       (if ediff-3way-job
		   (progn
		     (ediff-wordify
		      (ediff-get-diff-posn 'C 'beg n)
		      (ediff-get-diff-posn 'C 'end n)
		      ediff-buffer-C
		      tmp-buffer
		      ediff-control-buffer)
		     (setq file-C
			   (ediff-make-temp-file
			    tmp-buffer "fineDiffC" file-C))))

	       ;; save temp file names.
	       (setq ediff-temp-file-A file-A
		     ediff-temp-file-B file-B
		     ediff-temp-file-C file-C)

	       ;; set the new vector of fine diffs, if none exists
	       (cond ((and ediff-3way-job whitespace-A)
		      (ediff-setup-fine-diff-regions nil file-B file-C n))
		     ((and ediff-3way-job whitespace-B)
		      (ediff-setup-fine-diff-regions file-A nil file-C n))
		     ((and ediff-3way-job
			   ;; In merge-jobs, whitespace-C is t, since
			   ;; ediff-empty-diff-region-p returns t in this case
			   whitespace-C)
		      (ediff-setup-fine-diff-regions file-A file-B nil n))
		     (t
		      (ediff-setup-fine-diff-regions file-A file-B file-C n)))

	       (setq cumulative-fine-diff-length
		     (+ (length (ediff-get-fine-diff-vector n 'A))
			(length (ediff-get-fine-diff-vector n 'B))
			;; in merge jobs, the merge buffer is never refined
			(if (and file-C (not ediff-merge-job))
			    (length (ediff-get-fine-diff-vector n 'C))
			  0)))

	       (cond ((or
		       ;; all regions are white space
		       (and whitespace-A whitespace-B whitespace-C)
		       ;; none is white space and no fine diffs detected
		       (and (not whitespace-A)
			    (not whitespace-B)
			    (not (and ediff-3way-job whitespace-C))
			    (eq cumulative-fine-diff-length 0)))
		      (ediff-mark-diff-as-space-only n t)
		      (ediff-message-if-verbose
		       "Only white-space differences in region %d" (1+ n)))
		     ((eq cumulative-fine-diff-length 0)
		      (ediff-message-if-verbose
		       "Only white-space differences in region %d %s"
		       (1+ n)
		       (cond (whitespace-A (ediff-mark-diff-as-space-only n 'A)
					   "in buffers B & C")
			     (whitespace-B (ediff-mark-diff-as-space-only n 'B)
					   "in buffers A & C")
			     (whitespace-C (ediff-mark-diff-as-space-only n 'C)
					   "in buffers A & B"))))
		     (t
		      (ediff-mark-diff-as-space-only n nil)))
	       )
	      ) ; end cond
	(ediff-set-fine-diff-properties n)
	)))