(rmail-redecode-body): Use eight-bit instead of obsolete
[bpt/emacs.git] / lisp / ediff-diff.el
CommitLineData
475f9031 1;;; ediff-diff.el --- diff-related utilities
b578f267 2
0d30b337 3;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
ae940284 4;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
475f9031 5
50a07e18 6;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
475f9031
KH
7
8;; This file is part of GNU Emacs.
9
eb3fa2cf 10;; GNU Emacs is free software: you can redistribute it and/or modify
475f9031 11;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
475f9031
KH
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
eb3fa2cf 21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
475f9031 22
3afbc435
PJ
23;;; Commentary:
24
b578f267 25;;; Code:
475f9031 26
ddc90f39 27
2d84cc27
MK
28(provide 'ediff-diff)
29
ddc90f39 30(eval-when-compile
8480ec72 31 (require 'ediff-util))
ddc90f39 32
b578f267 33(require 'ediff-init)
475f9031 34
ddc90f39 35(defgroup ediff-diff nil
3b9ae202 36 "Diff related utilities."
ddc90f39
MK
37 :prefix "ediff-"
38 :group 'ediff)
39
7d027816 40(defcustom ediff-diff-program "diff"
9201cc28 41 "Program to use for generating the differential of the two files."
7d027816
MK
42 :type 'string
43 :group 'ediff-diff)
44(defcustom ediff-diff3-program "diff3"
9201cc28 45 "Program to be used for three-way comparison.
7d027816
MK
46Must produce output compatible with Unix's diff3 program."
47 :type 'string
48 :group 'ediff-diff)
49
513bea45 50
7d027816 51;; The following functions must precede all defcustom-defined variables.
4ae69eac 52
ec6aebe8
MK
53(fset 'ediff-set-actual-diff-options '(lambda () nil))
54
ddc90f39 55(defcustom ediff-shell
475f9031 56 (cond ((eq system-type 'emx) "cmd") ; OS/2
bbe6126c
MK
57 ((memq system-type '(ms-dos windows-nt windows-95))
58 shell-file-name) ; no standard name on MS-DOS
475f9031 59 (t "sh")) ; UNIX
9201cc28 60 "The shell used to run diff and patch.
50a07e18
MK
61If user's .profile or .cshrc files are set up correctly, any shell
62will do. However, some people set $prompt or other things
63incorrectly, which leads to undesirable output messages. These may
64cause Ediff to fail. In such a case, set `ediff-shell' to a shell that
65you are not using or, better, fix your shell's startup file."
ddc90f39
MK
66 :type 'string
67 :group 'ediff-diff)
475f9031 68
328b4b70 69(defcustom ediff-cmp-program "cmp"
9201cc28 70 "Utility to use to determine if two files are identical.
328b4b70
MK
71It must return code 0, if its arguments are identical files."
72 :type 'string
73 :group 'ediff-diff)
475f9031 74
3af0304a 75(defcustom ediff-cmp-options nil
9201cc28 76 "Options to pass to `ediff-cmp-program'.
ff4968b6 77If GNU diff is used as `ediff-cmp-program', then the most useful options
50a07e18 78are `-I REGEXP', to ignore changes whose lines match the REGEXP."
3af0304a
MK
79 :type '(repeat string)
80 :group 'ediff-diff)
81
33468a59
MK
82(defun ediff-set-diff-options (symbol value)
83 (set symbol value)
84 (ediff-set-actual-diff-options))
85
86(defcustom ediff-diff-options
87 (if (memq system-type '(ms-dos windows-nt windows-95)) "--binary" "")
9201cc28 88 "Options to pass to `ediff-diff-program'.
09fd8197 89If Unix diff is used as `ediff-diff-program',
c6a85d16
MK
90then a useful option is `-w', to ignore space.
91Options `-c', `-u', and `-i' are not allowed. Case sensitivity can be
92toggled interactively using \\[ediff-toggle-ignore-case].
93
33468a59
MK
94Do not remove the default options. If you need to change this variable, add new
95options after the default ones.
96
c6a85d16 97This variable is not for customizing the look of the differences produced by
36ba07ae 98the command \\[ediff-show-diff-output]. Use the variable
c6a85d16 99`ediff-custom-diff-options' for that."
33468a59 100 :set 'ediff-set-diff-options
ddc90f39
MK
101 :type 'string
102 :group 'ediff-diff)
475f9031 103
b6178721
MK
104(ediff-defvar-local ediff-ignore-case nil
105 "*If t, skip over difference regions that differ only in letter case.
106This variable can be set either in .emacs or toggled interactively.
107Use `setq-default' if setting it in .emacs")
108
109(defcustom ediff-ignore-case-option "-i"
9201cc28 110 "Option that causes the diff program to ignore case of letters."
b6178721
MK
111 :type 'string
112 :group 'ediff-diff)
113
114(defcustom ediff-ignore-case-option3 ""
9201cc28 115 "Option that causes the diff3 program to ignore case of letters.
b6178721
MK
116GNU diff3 doesn't have such an option."
117 :type 'string
118 :group 'ediff-diff)
119
120;; the actual options used in comparison
ec6aebe8 121(ediff-defvar-local ediff-actual-diff-options ediff-diff-options "")
b6178721 122
ddc90f39 123(defcustom ediff-custom-diff-program ediff-diff-program
9201cc28 124 "Program to use for generating custom diff output for saving it in a file.
ddc90f39
MK
125This output is not used by Ediff internally."
126 :type 'string
127 :group 'ediff-diff)
128(defcustom ediff-custom-diff-options "-c"
9201cc28 129 "Options to pass to `ediff-custom-diff-program'."
ddc90f39
MK
130 :type 'string
131 :group 'ediff-diff)
475f9031
KH
132
133;;; Support for diff3
134
4960e757 135(defvar ediff-match-diff3-line "^====\\(.?\\)\C-m?$"
475f9031 136 "Pattern to match lines produced by diff3 that describe differences.")
50a07e18 137(defcustom ediff-diff3-options ""
9201cc28 138 "Options to pass to `ediff-diff3-program'."
33468a59 139 :set 'ediff-set-diff-options
ddc90f39
MK
140 :type 'string
141 :group 'ediff-diff)
b6178721
MK
142
143;; the actual options used in comparison
ec6aebe8 144(ediff-defvar-local ediff-actual-diff3-options ediff-diff3-options "")
b6178721 145
ddc90f39 146(defcustom ediff-diff3-ok-lines-regexp
bbe6126c 147 "^\\([1-3]:\\|====\\| \\|.*Warning *:\\|.*No newline\\|.*missing newline\\|^\C-m$\\)"
9201cc28 148 "Regexp that matches normal output lines from `ediff-diff3-program'.
ddc90f39
MK
149Lines that do not match are assumed to be error messages."
150 :type 'regexp
151 :group 'ediff-diff)
475f9031
KH
152
153;; keeps the status of the current diff in 3-way jobs.
154;; the status can be =diff(A), =diff(B), or =diff(A+B)
155(ediff-defvar-local ediff-diff-status "" "")
156
71296446 157
50a07e18 158;;; Fine differences
475f9031 159
4ae69eac 160(ediff-defvar-local ediff-auto-refine (if (ediff-has-face-support-p) 'on 'nix)
475f9031
KH
161 "If `on', Ediff auto-highlights fine diffs for the current diff region.
162If `off', auto-highlighting is not used. If `nix', no fine diffs are shown
163at all, unless the user force-refines the region by hitting `*'.
164
165This variable can be set either in .emacs or toggled interactively.
166Use `setq-default' if setting it in .emacs")
167
168(ediff-defvar-local ediff-ignore-similar-regions nil
169 "*If t, skip over difference regions that differ only in the white space and line breaks.
170This variable can be set either in .emacs or toggled interactively.
171Use `setq-default' if setting it in .emacs")
172
b6178721 173(ediff-defvar-local ediff-auto-refine-limit 14000
bbe6126c 174 "*Auto-refine only the regions of this size \(in bytes\) or less.")
71296446 175
475f9031
KH
176;;; General
177
50a07e18 178(defvar ediff-diff-ok-lines-regexp
c004db97
MK
179 (concat
180 "^\\("
181 "[0-9,]+[acd][0-9,]+\C-m?$"
182 "\\|[<>] "
183 "\\|---"
184 "\\|.*Warning *:"
185 "\\|.*No +newline"
186 "\\|.*missing +newline"
187 "\\|^\C-m?$"
188 "\\)")
475f9031
KH
189 "Regexp that matches normal output lines from `ediff-diff-program'.
190This is mostly lifted from Emerge, except that Ediff also considers
191warnings and `Missing newline'-type messages to be normal output.
192Lines that do not match are assumed to be error messages.")
193
c004db97
MK
194(defvar ediff-match-diff-line
195 (let ((x "\\([0-9]+\\)\\(\\|,\\([0-9]+\\)\\)"))
196 (concat "^" x "\\([acd]\\)" x "\C-m?$"))
475f9031
KH
197 "Pattern to match lines produced by diff that describe differences.")
198
199(ediff-defvar-local ediff-setup-diff-regions-function nil
200 "value is a function symbol depending on the kind of job is to be done.
201For 2-way jobs and for ediff-merge, it should be `ediff-setup-diff-regions'.
202For jobs requiring diff3, it should be `ediff-setup-diff-regions3'.
203
204The function should take three mandatory arguments, file-A, file-B, and
205file-C. It may ignore file C for diff2 jobs. It should also take
206one optional arguments, diff-number to refine.")
207
71296446 208
475f9031
KH
209;;; Functions
210
211;; Generate the difference vector and overlays for the two files
212;; With optional arg REG-TO-REFINE, refine this region.
213;; File-C argument is not used here. It is there just because
214;; ediff-setup-diff-regions is called via a funcall to
215;; ediff-setup-diff-regions-function, which can also have the value
216;; ediff-setup-diff-regions3, which takes 4 arguments.
217(defun ediff-setup-diff-regions (file-A file-B file-C)
c6a85d16
MK
218 ;; looking for '-c', '-i', '-u', or 'c', 'i', 'u' among clustered non-long options
219 (if (string-match "^-[ciu]\\| -[ciu]\\|\\(^\\| \\)-[^- ]+[ciu]"
608c89a9 220 ediff-diff-options)
c6a85d16 221 (error "Options `-c', `-u', and `-i' are not allowed in `ediff-diff-options'"))
71296446 222
bbe6126c 223 ;; create, if it doesn't exist
475f9031
KH
224 (or (ediff-buffer-live-p ediff-diff-buffer)
225 (setq ediff-diff-buffer
226 (get-buffer-create (ediff-unique-buffer-name "*ediff-diff" "*"))))
bbe6126c 227 (ediff-make-diff2-buffer ediff-diff-buffer file-A file-B)
475f9031 228 (ediff-prepare-error-list ediff-diff-ok-lines-regexp ediff-diff-buffer)
475f9031
KH
229 (ediff-convert-diffs-to-overlays
230 (ediff-extract-diffs
4ae69eac 231 ediff-diff-buffer ediff-word-mode ediff-narrow-bounds)))
bbe6126c 232
52fa07ba
MK
233;; Run the diff program on FILE1 and FILE2 and put the output in DIFF-BUFFER
234;; Return the size of DIFF-BUFFER
513bea45 235;; The return code isn't used in the program at present.
bbe6126c 236(defun ediff-make-diff2-buffer (diff-buffer file1 file2)
92c51e07
MK
237 (let ((file1-size (ediff-file-size file1))
238 (file2-size (ediff-file-size file2)))
239 (cond ((not (numberp file1-size))
240 (message "Can't find file: %s"
241 (ediff-abbreviate-file-name file1))
242 (sit-for 2)
243 ;; 1 is an error exit code
244 1)
245 ((not (numberp file2-size))
246 (message "Can't find file: %s"
247 (ediff-abbreviate-file-name file2))
248 (sit-for 2)
249 ;; 1 is an error exit code
250 1)
92c51e07
MK
251 (t (message "Computing differences between %s and %s ..."
252 (file-name-nondirectory file1)
253 (file-name-nondirectory file2))
254 ;; this erases the diff buffer automatically
255 (ediff-exec-process ediff-diff-program
256 diff-buffer
257 'synchronize
b6178721 258 ediff-actual-diff-options file1 file2)
92c51e07 259 (message "")
e756eb9f 260 (ediff-with-current-buffer diff-buffer
92c51e07 261 (buffer-size))))))
bbe6126c 262
71296446
JB
263
264
475f9031
KH
265;; If file-A/B/C is nil, do 2-way comparison with the non-nil buffers
266;; This function works for diff3 and diff2 jobs
267(defun ediff-setup-fine-diff-regions (file-A file-B file-C reg-num)
268 (or (ediff-buffer-live-p ediff-fine-diff-buffer)
269 (setq ediff-fine-diff-buffer
270 (get-buffer-create
271 (ediff-unique-buffer-name "*ediff-fine-diff" "*"))))
71296446 272
ab8a391e 273 (let (diff3-job diff-program diff-options ok-regexp diff-list)
475f9031
KH
274 (setq diff3-job ediff-3way-job
275 diff-program (if diff3-job ediff-diff3-program ediff-diff-program)
b6178721
MK
276 diff-options (if diff3-job
277 ediff-actual-diff3-options
278 ediff-actual-diff-options)
475f9031
KH
279 ok-regexp (if diff3-job
280 ediff-diff3-ok-lines-regexp
281 ediff-diff-ok-lines-regexp))
71296446 282
4ad42cb5
MK
283 (ediff-message-if-verbose "Refining difference region %d ..." (1+ reg-num))
284 (ediff-exec-process diff-program ediff-fine-diff-buffer 'synchronize
ab8a391e 285 diff-options
4ad42cb5
MK
286 ;; The shuffle below is because we can compare 3-way
287 ;; or in several 2-way fashions, like fA fC, fA fB,
288 ;; or fB fC.
289 (if file-A file-A file-B)
290 (if file-B file-B file-A)
291 (if diff3-job
292 (if file-C file-C file-B))
293 ) ; exec process
71296446 294
475f9031 295 (ediff-prepare-error-list ok-regexp ediff-fine-diff-buffer)
4ae69eac
MK
296 (ediff-message-if-verbose
297 "")
4ad42cb5 298 ;; "Refining difference region %d ... done" (1+ reg-num))
71296446 299
475f9031
KH
300 (setq diff-list
301 (if diff3-job
302 (ediff-extract-diffs3
303 ediff-fine-diff-buffer '3way-comparison 'word-mode)
304 (ediff-extract-diffs ediff-fine-diff-buffer 'word-mode)))
305 ;; fixup diff-list
306 (if diff3-job
307 (cond ((not file-A)
36ba07ae
JB
308 (mapc (lambda (elt)
309 (aset elt 0 nil)
310 (aset elt 1 nil))
311 (cdr diff-list)))
475f9031 312 ((not file-B)
36ba07ae
JB
313 (mapc (lambda (elt)
314 (aset elt 2 nil)
315 (aset elt 3 nil))
316 (cdr diff-list)))
475f9031 317 ((not file-C)
36ba07ae
JB
318 (mapc (lambda (elt)
319 (aset elt 4 nil)
320 (aset elt 5 nil))
321 (cdr diff-list)))
475f9031 322 ))
71296446 323
475f9031
KH
324 (ediff-convert-fine-diffs-to-overlays diff-list reg-num)
325 ))
71296446
JB
326
327
475f9031 328(defun ediff-prepare-error-list (ok-regexp diff-buff)
4ad42cb5
MK
329 (or (ediff-buffer-live-p ediff-error-buffer)
330 (setq ediff-error-buffer
331 (get-buffer-create (ediff-unique-buffer-name
332 "*ediff-errors" "*"))))
e756eb9f 333 (ediff-with-current-buffer ediff-error-buffer
e392d1cc 334 (setq buffer-undo-list t)
4ad42cb5 335 (erase-buffer)
e756eb9f 336 (insert (ediff-with-current-buffer diff-buff (buffer-string)))
4ad42cb5 337 (goto-char (point-min))
7c2fb837 338 (delete-matching-lines ok-regexp))
4ad42cb5 339 ;; If diff reports errors, show them then quit.
e756eb9f 340 (if (/= 0 (ediff-with-current-buffer ediff-error-buffer (buffer-size)))
4ad42cb5
MK
341 (let ((ctl-buf ediff-control-buffer)
342 (error-buf ediff-error-buffer))
343 (ediff-skip-unsuitable-frames)
344 (switch-to-buffer error-buf)
345 (ediff-kill-buffer-carefully ctl-buf)
50a07e18 346 (error "Errors in diff output. Diff output is in %S" diff-buff))))
475f9031
KH
347
348;; BOUNDS specifies visibility bounds to use.
349;; WORD-MODE tells whether we are in the word-mode or not.
350;; If WORD-MODE, also construct vector of diffs using word numbers.
351;; Else, use point values.
352;; This function handles diff-2 jobs including the case of
353;; merging buffers and files without ancestor.
354(defun ediff-extract-diffs (diff-buffer word-mode &optional bounds)
355 (let ((A-buffer ediff-buffer-A)
356 (B-buffer ediff-buffer-B)
357 (C-buffer ediff-buffer-C)
358 (a-prev 1) ; this is needed to set the first diff line correctly
b6178721 359 (a-prev-pt nil)
475f9031 360 (b-prev 1)
b6178721 361 (b-prev-pt nil)
475f9031 362 (c-prev 1)
b6178721 363 (c-prev-pt nil)
475f9031
KH
364 diff-list shift-A shift-B
365 )
09fd8197 366
475f9031
KH
367 ;; diff list contains word numbers, unless changed later
368 (setq diff-list (cons (if word-mode 'words 'points)
369 diff-list))
370 ;; we don't use visibility bounds for buffer C when merging
371 (if bounds
372 (setq shift-A
373 (ediff-overlay-start
374 (ediff-get-value-according-to-buffer-type 'A bounds))
50a07e18 375 shift-B
475f9031
KH
376 (ediff-overlay-start
377 (ediff-get-value-according-to-buffer-type 'B bounds))))
09fd8197 378
475f9031 379 ;; reset point in buffers A/B/C
e756eb9f 380 (ediff-with-current-buffer A-buffer
475f9031 381 (goto-char (if shift-A shift-A (point-min))))
e756eb9f 382 (ediff-with-current-buffer B-buffer
475f9031
KH
383 (goto-char (if shift-B shift-B (point-min))))
384 (if (ediff-buffer-live-p C-buffer)
e756eb9f 385 (ediff-with-current-buffer C-buffer
475f9031 386 (goto-char (point-min))))
71296446 387
e756eb9f 388 (ediff-with-current-buffer diff-buffer
475f9031
KH
389 (goto-char (point-min))
390 (while (re-search-forward ediff-match-diff-line nil t)
027a4b6b
JB
391 (let* ((a-begin (string-to-number (buffer-substring (match-beginning 1)
392 (match-end 1))))
475f9031
KH
393 (a-end (let ((b (match-beginning 3))
394 (e (match-end 3)))
395 (if b
027a4b6b 396 (string-to-number (buffer-substring b e))
475f9031
KH
397 a-begin)))
398 (diff-type (buffer-substring (match-beginning 4) (match-end 4)))
027a4b6b
JB
399 (b-begin (string-to-number (buffer-substring (match-beginning 5)
400 (match-end 5))))
475f9031
KH
401 (b-end (let ((b (match-beginning 7))
402 (e (match-end 7)))
403 (if b
027a4b6b 404 (string-to-number (buffer-substring b e))
475f9031
KH
405 b-begin)))
406 a-begin-pt a-end-pt b-begin-pt b-end-pt
407 c-begin c-end c-begin-pt c-end-pt)
408 ;; fix the beginning and end numbers, because diff is somewhat
409 ;; strange about how it numbers lines
410 (if (string-equal diff-type "a")
411 (setq b-end (1+ b-end)
412 a-begin (1+ a-begin)
413 a-end a-begin)
414 (if (string-equal diff-type "d")
415 (setq a-end (1+ a-end)
416 b-begin (1+ b-begin)
417 b-end b-begin)
418 ;; (string-equal diff-type "c")
419 (setq a-end (1+ a-end)
420 b-end (1+ b-end))))
71296446 421
475f9031
KH
422 (if (eq ediff-default-variant 'default-B)
423 (setq c-begin b-begin
424 c-end b-end)
425 (setq c-begin a-begin
426 c-end a-end))
71296446 427
475f9031
KH
428 ;; compute main diff vector
429 (if word-mode
430 ;; make diff-list contain word numbers
50a07e18 431 (setq diff-list
475f9031
KH
432 (nconc diff-list
433 (list
434 (if (ediff-buffer-live-p C-buffer)
435 (vector (- a-begin a-prev) (- a-end a-begin)
436 (- b-begin b-prev) (- b-end b-begin)
437 (- c-begin c-prev) (- c-end c-begin)
4ad42cb5
MK
438 nil nil ; dummy ancestor
439 nil ; state of diff
440 nil ; state of merge
441 nil ; state of ancestor
475f9031
KH
442 )
443 (vector (- a-begin a-prev) (- a-end a-begin)
444 (- b-begin b-prev) (- b-end b-begin)
445 nil nil ; dummy buf C
4ad42cb5 446 nil nil ; dummy ancestor
475f9031
KH
447 nil ; state of diff
448 nil ; state of merge
4ad42cb5 449 nil ; state of ancestor
475f9031
KH
450 ))
451 ))
452 a-prev a-end
453 b-prev b-end
454 c-prev c-end)
455 ;; else convert lines to points
e756eb9f 456 (ediff-with-current-buffer A-buffer
8ea74b0e
MK
457 (let ((longlines-mode-val
458 (if (and (boundp 'longlines-mode) longlines-mode) 1 0)))
459 ;; we must disable and then restore longlines-mode
460 (if (eq longlines-mode-val 1)
461 (longlines-mode 0))
b6178721 462 (goto-char (or a-prev-pt shift-A (point-min)))
8ea74b0e
MK
463 (forward-line (- a-begin a-prev))
464 (setq a-begin-pt (point))
465 (forward-line (- a-end a-begin))
466 (setq a-end-pt (point)
b6178721
MK
467 a-prev a-end
468 a-prev-pt a-end-pt)
8ea74b0e
MK
469 (if (eq longlines-mode-val 1)
470 (longlines-mode longlines-mode-val))
471 ))
e756eb9f 472 (ediff-with-current-buffer B-buffer
8ea74b0e
MK
473 (let ((longlines-mode-val
474 (if (and (boundp 'longlines-mode) longlines-mode) 1 0)))
475 (if (eq longlines-mode-val 1)
476 (longlines-mode 0))
b6178721 477 (goto-char (or b-prev-pt shift-B (point-min)))
8ea74b0e
MK
478 (forward-line (- b-begin b-prev))
479 (setq b-begin-pt (point))
480 (forward-line (- b-end b-begin))
481 (setq b-end-pt (point)
b6178721
MK
482 b-prev b-end
483 b-prev-pt b-end-pt)
8ea74b0e
MK
484 (if (eq longlines-mode-val 1)
485 (longlines-mode longlines-mode-val))
486 ))
475f9031 487 (if (ediff-buffer-live-p C-buffer)
e756eb9f 488 (ediff-with-current-buffer C-buffer
8ea74b0e
MK
489 (let ((longlines-mode-val
490 (if (and (boundp 'longlines-mode) longlines-mode) 1 0)))
491 (if (eq longlines-mode-val 1)
492 (longlines-mode 0))
b6178721 493 (goto-char (or c-prev-pt (point-min)))
8ea74b0e
MK
494 (forward-line (- c-begin c-prev))
495 (setq c-begin-pt (point))
496 (forward-line (- c-end c-begin))
497 (setq c-end-pt (point)
b6178721
MK
498 c-prev c-end
499 c-prev-pt c-end-pt)
8ea74b0e
MK
500 (if (eq longlines-mode-val 1)
501 (longlines-mode longlines-mode-val))
502 )))
50a07e18 503 (setq diff-list
475f9031
KH
504 (nconc
505 diff-list
506 (list
507 (if (ediff-buffer-live-p C-buffer)
508 (vector
509 a-begin-pt a-end-pt b-begin-pt b-end-pt
510 c-begin-pt c-end-pt
4ad42cb5 511 nil nil ; dummy ancestor
475f9031
KH
512 ;; state of diff
513 ;; shows which buff is different from the other two
514 (if (eq ediff-default-variant 'default-B) 'A 'B)
4ad42cb5
MK
515 ediff-default-variant ; state of merge
516 nil ; state of ancestor
475f9031 517 )
4ad42cb5
MK
518 (vector a-begin-pt a-end-pt
519 b-begin-pt b-end-pt
520 nil nil ; dummy buf C
521 nil nil ; dummy ancestor
522 nil nil ; dummy state of diff & merge
523 nil ; dummy state of ancestor
50a07e18 524 )))
475f9031 525 )))
71296446 526
e756eb9f 527 ))) ; end ediff-with-current-buffer
475f9031
KH
528 diff-list
529 ))
71296446 530
475f9031 531
4ad42cb5
MK
532(defun ediff-convert-diffs-to-overlays (diff-list)
533 (ediff-set-diff-overlays-in-one-buffer 'A diff-list)
534 (ediff-set-diff-overlays-in-one-buffer 'B diff-list)
535 (if ediff-3way-job
536 (ediff-set-diff-overlays-in-one-buffer 'C diff-list))
537 (if ediff-merge-with-ancestor-job
538 (ediff-set-diff-overlays-in-one-buffer 'Ancestor diff-list))
539 ;; set up vector showing the status of merge regions
540 (if ediff-merge-job
541 (setq ediff-state-of-merge
542 (vconcat
3af0304a
MK
543 (mapcar (lambda (elt)
544 (let ((state-of-merge (aref elt 9))
545 (state-of-ancestor (aref elt 10)))
546 (vector
547 ;; state of merge: prefers/default-A/B or combined
548 (if state-of-merge (format "%S" state-of-merge))
549 ;; whether the ancestor region is empty
550 state-of-ancestor)))
4ad42cb5
MK
551 ;; the first elt designates type of list
552 (cdr diff-list))
553 )))
554 (message "Processing difference regions ... done"))
555
71296446 556
475f9031
KH
557(defun ediff-set-diff-overlays-in-one-buffer (buf-type diff-list)
558 (let* ((current-diff -1)
559 (buff (ediff-get-buffer buf-type))
17561e4f 560 (ctl-buf ediff-control-buffer)
475f9031
KH
561 ;; ediff-extract-diffs puts the type of diff-list as the first elt
562 ;; of this list. The type is either 'points or 'words
563 (diff-list-type (car diff-list))
564 (shift (ediff-overlay-start
565 (ediff-get-value-according-to-buffer-type
566 buf-type ediff-narrow-bounds)))
567 (limit (ediff-overlay-end
50a07e18 568 (ediff-get-value-according-to-buffer-type
475f9031
KH
569 buf-type ediff-narrow-bounds)))
570 diff-overlay-list list-element total-diffs
4ad42cb5 571 begin end pt-saved overlay state-of-diff)
475f9031
KH
572
573 (setq diff-list (cdr diff-list)) ; discard diff list type
574 (setq total-diffs (length diff-list))
71296446 575
475f9031 576 ;; shift, if necessary
e756eb9f 577 (ediff-with-current-buffer buff (setq pt-saved shift))
71296446 578
475f9031
KH
579 (while diff-list
580 (setq current-diff (1+ current-diff)
581 list-element (car diff-list)
582 begin (aref list-element (cond ((eq buf-type 'A) 0)
583 ((eq buf-type 'B) 2)
4ad42cb5
MK
584 ((eq buf-type 'C) 4)
585 (t 6))) ; Ancestor
475f9031
KH
586 end (aref list-element (cond ((eq buf-type 'A) 1)
587 ((eq buf-type 'B) 3)
4ad42cb5
MK
588 ((eq buf-type 'C) 5)
589 (t 7))) ; Ancestor
590 state-of-diff (aref list-element 8)
591 )
71296446 592
475f9031 593 (cond ((and (not (eq buf-type state-of-diff))
4ad42cb5 594 (not (eq buf-type 'Ancestor))
475f9031
KH
595 (memq state-of-diff '(A B C)))
596 (setq state-of-diff
597 (car (delq buf-type (delq state-of-diff (list 'A 'B 'C)))))
598 (setq state-of-diff (format "=diff(%S)" state-of-diff))
475f9031 599 )
4ad42cb5 600 (t (setq state-of-diff nil)))
71296446 601
475f9031
KH
602 ;; Put overlays at appropriate places in buffer
603 ;; convert word numbers to points, if necessary
604 (if (eq diff-list-type 'words)
605 (progn
e756eb9f 606 (ediff-with-current-buffer buff (goto-char pt-saved))
17561e4f
MK
607 (ediff-with-current-buffer ctl-buf
608 (setq begin (ediff-goto-word (1+ begin) buff)
609 end (ediff-goto-word end buff 'end)))
475f9031
KH
610 (if (> end limit) (setq end limit))
611 (if (> begin end) (setq begin end))
e756eb9f 612 (setq pt-saved (ediff-with-current-buffer buff (point)))))
475f9031 613 (setq overlay (ediff-make-bullet-proof-overlay begin end buff))
71296446 614
475f9031
KH
615 (ediff-overlay-put overlay 'priority ediff-shadow-overlay-priority)
616 (ediff-overlay-put overlay 'ediff-diff-num current-diff)
4ae69eac 617 (if (and (ediff-has-face-support-p)
4ad42cb5
MK
618 ediff-use-faces ediff-highlight-all-diffs)
619 (ediff-set-overlay-face
620 overlay (ediff-background-face buf-type current-diff)))
475f9031
KH
621
622 (if (= 0 (mod current-diff 10))
623 (message "Buffer %S: Processing difference region %d of %d"
624 buf-type current-diff total-diffs))
3af0304a
MK
625 ;; Record all overlays for this difference.
626 ;; The 2-d elt, nil, is a place holder for the fine diff vector.
627 ;; The 3-d elt, nil, is a place holder for no-fine-diffs flag.
628 ;; The 4-th elt says which diff region is different from the other two
629 ;; (3-way jobs only).
475f9031
KH
630 (setq diff-overlay-list
631 (nconc
632 diff-overlay-list
4ad42cb5 633 (list (vector overlay nil nil state-of-diff)))
475f9031
KH
634 diff-list
635 (cdr diff-list))
636 ) ; while
71296446 637
e756eb9f 638 (set (ediff-get-symbol-from-alist buf-type ediff-difference-vector-alist)
4ad42cb5 639 (vconcat diff-overlay-list))
475f9031 640 ))
4ad42cb5 641
475f9031
KH
642;; `n' is the diff region to work on. Default is ediff-current-difference.
643;; if `flag' is 'noforce then make fine-diffs only if this region's fine
644;; diffs have not been computed before.
645;; if `flag' is 'skip then don't compute fine diffs for this region.
50a07e18 646(defun ediff-make-fine-diffs (&optional n flag)
475f9031 647 (or n (setq n ediff-current-difference))
71296446 648
475f9031 649 (if (< ediff-number-of-differences 1)
bbe6126c 650 (error ediff-NO-DIFFERENCES))
71296446 651
475f9031
KH
652 (if ediff-word-mode
653 (setq flag 'skip
654 ediff-auto-refine 'nix))
71296446 655
475f9031
KH
656 (or (< n 0)
657 (>= n ediff-number-of-differences)
658 ;; n is within the range
659 (let ((tmp-buffer (get-buffer-create ediff-tmp-buffer))
660 (file-A ediff-temp-file-A)
661 (file-B ediff-temp-file-B)
662 (file-C ediff-temp-file-C)
663 (empty-A (ediff-empty-diff-region-p n 'A))
664 (empty-B (ediff-empty-diff-region-p n 'B))
665 (empty-C (ediff-empty-diff-region-p n 'C))
666 (whitespace-A (ediff-whitespace-diff-region-p n 'A))
667 (whitespace-B (ediff-whitespace-diff-region-p n 'B))
668 (whitespace-C (ediff-whitespace-diff-region-p n 'C))
669 cumulative-fine-diff-length)
71296446 670
ddc90f39 671 (cond ;; If one of the regions is empty (or 2 in 3way comparison)
4ad42cb5
MK
672 ;; then don't refine.
673 ;; If the region happens to be entirely whitespace or empty then
674 ;; mark as such.
475f9031
KH
675 ((> (length (delq nil (list empty-A empty-B empty-C))) 1)
676 (if (and (ediff-looks-like-combined-merge n)
677 ediff-merge-job)
678 (ediff-set-fine-overlays-in-one-buffer 'C nil n))
4ad42cb5
MK
679 (if ediff-3way-comparison-job
680 (ediff-message-if-verbose
681 "Region %d is empty in all buffers but %S"
50a07e18 682 (1+ n)
4ad42cb5
MK
683 (cond ((not empty-A) 'A)
684 ((not empty-B) 'B)
685 ((not empty-C) 'C)))
686 (ediff-message-if-verbose
687 "Region %d in buffer %S is empty"
50a07e18 688 (1+ n)
4ad42cb5
MK
689 (cond (empty-A 'A)
690 (empty-B 'B)
691 (empty-C 'C)))
692 )
bbe6126c 693 ;; if all regions happen to be whitespace
4ad42cb5 694 (if (and whitespace-A whitespace-B whitespace-C)
bbe6126c 695 ;; mark as space only
475f9031 696 (ediff-mark-diff-as-space-only n t)
bbe6126c
MK
697 ;; if some regions are white and others don't, then mark as
698 ;; non-white-space-only
475f9031 699 (ediff-mark-diff-as-space-only n nil)))
ddc90f39
MK
700
701 ;; don't compute fine diffs if diff vector exists
702 ((and (eq flag 'noforce) (ediff-get-fine-diff-vector n 'A))
703 (if (ediff-no-fine-diffs-p n)
704 (message
705 "Only white-space differences in region %d %s"
706 (1+ n)
707 (cond ((eq (ediff-no-fine-diffs-p n) 'A)
708 "in buffers B & C")
709 ((eq (ediff-no-fine-diffs-p n) 'B)
710 "in buffers A & C")
711 ((eq (ediff-no-fine-diffs-p n) 'C)
712 "in buffers A & B")
713 (t "")))))
475f9031
KH
714 ;; don't compute fine diffs for this region
715 ((eq flag 'skip)
716 (or (ediff-get-fine-diff-vector n 'A)
717 (memq ediff-auto-refine '(off nix))
4ad42cb5 718 (ediff-message-if-verbose
3af0304a 719 "Region %d exceeds the auto-refinement limit. Type `%s' to refine"
475f9031 720 (1+ n)
4ad42cb5
MK
721 (substitute-command-keys
722 "\\[ediff-make-or-kill-fine-diffs]")
475f9031
KH
723 )))
724 (t
475f9031
KH
725 ;; recompute fine diffs
726 (ediff-wordify
727 (ediff-get-diff-posn 'A 'beg n)
728 (ediff-get-diff-posn 'A 'end n)
729 ediff-buffer-A
730 tmp-buffer
731 ediff-control-buffer)
4ad42cb5
MK
732 (setq file-A
733 (ediff-make-temp-file tmp-buffer "fineDiffA" file-A))
71296446 734
475f9031
KH
735 (ediff-wordify
736 (ediff-get-diff-posn 'B 'beg n)
737 (ediff-get-diff-posn 'B 'end n)
738 ediff-buffer-B
739 tmp-buffer
740 ediff-control-buffer)
4ad42cb5
MK
741 (setq file-B
742 (ediff-make-temp-file tmp-buffer "fineDiffB" file-B))
71296446 743
475f9031
KH
744 (if ediff-3way-job
745 (progn
746 (ediff-wordify
747 (ediff-get-diff-posn 'C 'beg n)
748 (ediff-get-diff-posn 'C 'end n)
749 ediff-buffer-C
750 tmp-buffer
751 ediff-control-buffer)
4ad42cb5
MK
752 (setq file-C
753 (ediff-make-temp-file
754 tmp-buffer "fineDiffC" file-C))))
71296446 755
475f9031
KH
756 ;; save temp file names.
757 (setq ediff-temp-file-A file-A
758 ediff-temp-file-B file-B
759 ediff-temp-file-C file-C)
71296446 760
475f9031
KH
761 ;; set the new vector of fine diffs, if none exists
762 (cond ((and ediff-3way-job whitespace-A)
763 (ediff-setup-fine-diff-regions nil file-B file-C n))
764 ((and ediff-3way-job whitespace-B)
765 (ediff-setup-fine-diff-regions file-A nil file-C n))
766 ((and ediff-3way-job
bbe6126c
MK
767 ;; In merge-jobs, whitespace-C is t, since
768 ;; ediff-empty-diff-region-p returns t in this case
769 whitespace-C)
475f9031
KH
770 (ediff-setup-fine-diff-regions file-A file-B nil n))
771 (t
772 (ediff-setup-fine-diff-regions file-A file-B file-C n)))
71296446 773
475f9031
KH
774 (setq cumulative-fine-diff-length
775 (+ (length (ediff-get-fine-diff-vector n 'A))
bbe6126c
MK
776 (length (ediff-get-fine-diff-vector n 'B))
777 ;; in merge jobs, the merge buffer is never refined
778 (if (and file-C (not ediff-merge-job))
779 (length (ediff-get-fine-diff-vector n 'C))
780 0)))
71296446 781
475f9031
KH
782 (cond ((or
783 ;; all regions are white space
784 (and whitespace-A whitespace-B whitespace-C)
785 ;; none is white space and no fine diffs detected
786 (and (not whitespace-A)
787 (not whitespace-B)
788 (not (and ediff-3way-job whitespace-C))
789 (eq cumulative-fine-diff-length 0)))
790 (ediff-mark-diff-as-space-only n t)
4ad42cb5 791 (ediff-message-if-verbose
475f9031
KH
792 "Only white-space differences in region %d" (1+ n)))
793 ((eq cumulative-fine-diff-length 0)
4ad42cb5 794 (ediff-message-if-verbose
475f9031
KH
795 "Only white-space differences in region %d %s"
796 (1+ n)
ddc90f39
MK
797 (cond (whitespace-A (ediff-mark-diff-as-space-only n 'A)
798 "in buffers B & C")
799 (whitespace-B (ediff-mark-diff-as-space-only n 'B)
800 "in buffers A & C")
801 (whitespace-C (ediff-mark-diff-as-space-only n 'C)
802 "in buffers A & B"))))
50a07e18 803 (t
475f9031
KH
804 (ediff-mark-diff-as-space-only n nil)))
805 )
806 ) ; end cond
807 (ediff-set-fine-diff-properties n)
808 )))
71296446 809
475f9031
KH
810;; Interface to ediff-make-fine-diffs. Checks for auto-refine limit, etc.
811(defun ediff-install-fine-diff-if-necessary (n)
743a79af
MK
812 (cond ((and (eq ediff-auto-refine 'on)
813 ediff-use-faces
814 (not (eq ediff-highlighting-style 'off))
815 (not (eq ediff-highlighting-style 'ascii)))
475f9031
KH
816 (if (and
817 (> ediff-auto-refine-limit
818 (- (ediff-get-diff-posn 'A 'end n)
819 (ediff-get-diff-posn 'A 'beg n)))
820 (> ediff-auto-refine-limit
821 (- (ediff-get-diff-posn 'B 'end n)
822 (ediff-get-diff-posn 'B 'beg n))))
823 (ediff-make-fine-diffs n 'noforce)
824 (ediff-make-fine-diffs n 'skip)))
71296446 825
4837b516 826 ;; highlight if fine diffs already exist
475f9031
KH
827 ((eq ediff-auto-refine 'off)
828 (ediff-make-fine-diffs n 'skip))))
71296446
JB
829
830
475f9031
KH
831;; if fine diff vector is not set for diff N, then do nothing
832(defun ediff-set-fine-diff-properties (n &optional default)
4ae69eac 833 (or (not (ediff-has-face-support-p))
475f9031
KH
834 (< n 0)
835 (>= n ediff-number-of-differences)
4ae69eac 836 ;; when faces are supported, set faces and priorities of fine overlays
475f9031
KH
837 (progn
838 (ediff-set-fine-diff-properties-in-one-buffer 'A n default)
839 (ediff-set-fine-diff-properties-in-one-buffer 'B n default)
840 (if ediff-3way-job
841 (ediff-set-fine-diff-properties-in-one-buffer 'C n default)))))
71296446 842
475f9031
KH
843(defun ediff-set-fine-diff-properties-in-one-buffer (buf-type
844 n &optional default)
845 (let ((fine-diff-vector (ediff-get-fine-diff-vector n buf-type))
50a07e18 846 (face (if default
475f9031 847 'default
33468a59
MK
848 (ediff-get-symbol-from-alist
849 buf-type ediff-fine-diff-face-alist)
850 ))
475f9031
KH
851 (priority (if default
852 0
853 (1+ (or (ediff-overlay-get
854 (symbol-value
e756eb9f
MK
855 (ediff-get-symbol-from-alist
856 buf-type
857 ediff-current-diff-overlay-alist))
475f9031
KH
858 'priority)
859 0)))))
3af0304a
MK
860 (mapcar (lambda (overl)
861 (ediff-set-overlay-face overl face)
862 (ediff-overlay-put overl 'priority priority))
863 fine-diff-vector)))
71296446 864
086171bf 865;; Set overlays over the regions that denote delimiters
475f9031 866(defun ediff-set-fine-overlays-for-combined-merge (diff-list reg-num)
086171bf
MK
867 (let (overlay overlay-list)
868 (while diff-list
869 (condition-case nil
870 (setq overlay
871 (ediff-make-bullet-proof-overlay
872 (nth 0 diff-list) (nth 1 diff-list) ediff-buffer-C))
873 (error ""))
874 (setq overlay-list (cons overlay overlay-list))
875 (if (> (length diff-list) 1)
876 (setq diff-list (cdr (cdr diff-list)))
877 (error "ediff-set-fine-overlays-for-combined-merge: corrupt list of
878delimiter regions"))
879 )
880 (setq overlay-list (reverse overlay-list))
881 (ediff-set-fine-diff-vector
882 reg-num 'C (apply 'vector overlay-list))
475f9031 883 ))
71296446
JB
884
885
475f9031
KH
886;; Convert diff list to overlays for a given DIFF-REGION
887;; in buffer of type BUF-TYPE
888(defun ediff-set-fine-overlays-in-one-buffer (buf-type diff-list region-num)
889 (let* ((current-diff -1)
890 (reg-start (ediff-get-diff-posn buf-type 'beg region-num))
891 (buff (ediff-get-buffer buf-type))
17561e4f 892 (ctl-buf ediff-control-buffer)
475f9031
KH
893 combined-merge-diff-list
894 diff-overlay-list list-element
895 begin end overlay)
896
897 (ediff-clear-fine-differences-in-one-buffer region-num buf-type)
898 (setq diff-list (cdr diff-list)) ; discard list type (words or points)
e756eb9f 899 (ediff-with-current-buffer buff (goto-char reg-start))
71296446 900
475f9031
KH
901 ;; if it is a combined merge then set overlays in buff C specially
902 (if (and ediff-merge-job (eq buf-type 'C)
903 (setq combined-merge-diff-list
904 (ediff-looks-like-combined-merge region-num)))
905 (ediff-set-fine-overlays-for-combined-merge
906 combined-merge-diff-list region-num)
907 ;; regular fine diff
908 (while diff-list
909 (setq current-diff (1+ current-diff)
910 list-element (car diff-list)
911 begin (aref list-element (cond ((eq buf-type 'A) 0)
912 ((eq buf-type 'B) 2)
913 (t 4))) ; buf C
914 end (aref list-element (cond ((eq buf-type 'A) 1)
915 ((eq buf-type 'B) 3)
916 (t 5)))) ; buf C
917 (if (not (or begin end))
918 () ; skip this diff
919 ;; Put overlays at appropriate places in buffers
920 ;; convert lines to points, if necessary
17561e4f
MK
921 (ediff-with-current-buffer ctl-buf
922 (setq begin (ediff-goto-word (1+ begin) buff)
923 end (ediff-goto-word end buff 'end)))
475f9031
KH
924 (setq overlay (ediff-make-bullet-proof-overlay begin end buff))
925 ;; record all overlays for this difference region
926 (setq diff-overlay-list (nconc diff-overlay-list (list overlay))))
71296446 927
475f9031
KH
928 (setq diff-list (cdr diff-list))
929 ) ; while
930 ;; convert the list of difference information into a vector
931 ;; for fast access
50a07e18 932 (ediff-set-fine-diff-vector
4ad42cb5 933 region-num buf-type (vconcat diff-overlay-list))
475f9031
KH
934 )))
935
936
65efc538 937(defun ediff-convert-fine-diffs-to-overlays (diff-list region-num)
50a07e18
MK
938 (ediff-set-fine-overlays-in-one-buffer 'A diff-list region-num)
939 (ediff-set-fine-overlays-in-one-buffer 'B diff-list region-num)
940 (if ediff-3way-job
941 (ediff-set-fine-overlays-in-one-buffer 'C diff-list region-num)
942 ))
943
944
475f9031
KH
945;; Stolen from emerge.el
946(defun ediff-get-diff3-group (file)
947 ;; This save-excursion allows ediff-get-diff3-group to be called for the
948 ;; various groups of lines (1, 2, 3) in any order, and for the lines to
949 ;; appear in any order. The reason this is necessary is that Gnu diff3
950 ;; can produce the groups in the order 1, 2, 3 or 1, 3, 2.
951 (save-excursion
952 (re-search-forward
4960e757 953 (concat "^" file ":\\([0-9]+\\)\\(,\\([0-9]+\\)\\)?\\([ac]\\)\C-m?$"))
475f9031
KH
954 (beginning-of-line 2)
955 ;; treatment depends on whether it is an "a" group or a "c" group
956 (if (string-equal (buffer-substring (match-beginning 4) (match-end 4)) "c")
957 ;; it is a "c" group
958 (if (match-beginning 2)
959 ;; it has two numbers
027a4b6b 960 (list (string-to-number
475f9031 961 (buffer-substring (match-beginning 1) (match-end 1)))
027a4b6b 962 (1+ (string-to-number
475f9031
KH
963 (buffer-substring (match-beginning 3) (match-end 3)))))
964 ;; it has one number
027a4b6b 965 (let ((x (string-to-number
475f9031
KH
966 (buffer-substring (match-beginning 1) (match-end 1)))))
967 (list x (1+ x))))
968 ;; it is an "a" group
027a4b6b 969 (let ((x (1+ (string-to-number
475f9031
KH
970 (buffer-substring (match-beginning 1) (match-end 1))))))
971 (list x x)))))
972
973
974;; If WORD-MODE, construct vector of diffs using word numbers.
975;; Else, use point values.
976;; WORD-MODE also tells if we are in the word-mode or not.
977;; If THREE-WAY-COMP, then it is a 3-way comparison. Else, it is merging
4ad42cb5
MK
978;; with ancestor, in which case buffer-C contents is identical to buffer-A/B,
979;; contents (unless buffer-A is narrowed) depending on ediff-default-variant's
980;; value.
475f9031
KH
981;; BOUNDS specifies visibility bounds to use.
982(defun ediff-extract-diffs3 (diff-buffer word-mode three-way-comp
983 &optional bounds)
984 (let ((A-buffer ediff-buffer-A)
985 (B-buffer ediff-buffer-B)
986 (C-buffer ediff-buffer-C)
4ad42cb5 987 (anc-buffer ediff-ancestor-buffer)
475f9031 988 (a-prev 1) ; needed to set the first diff line correctly
b6178721 989 (a-prev-pt nil)
475f9031 990 (b-prev 1)
b6178721 991 (b-prev-pt nil)
475f9031 992 (c-prev 1)
b6178721 993 (c-prev-pt nil)
4ad42cb5 994 (anc-prev 1)
475f9031
KH
995 diff-list shift-A shift-B shift-C
996 )
71296446 997
475f9031
KH
998 ;; diff list contains word numbers or points, depending on word-mode
999 (setq diff-list (cons (if word-mode 'words 'points)
1000 diff-list))
1001 (if bounds
1002 (setq shift-A
1003 (ediff-overlay-start
1004 (ediff-get-value-according-to-buffer-type 'A bounds))
50a07e18 1005 shift-B
475f9031
KH
1006 (ediff-overlay-start
1007 (ediff-get-value-according-to-buffer-type 'B bounds))
50a07e18 1008 shift-C
475f9031
KH
1009 (if three-way-comp
1010 (ediff-overlay-start
1011 (ediff-get-value-according-to-buffer-type 'C bounds)))))
71296446 1012
475f9031 1013 ;; reset point in buffers A, B, C
e756eb9f 1014 (ediff-with-current-buffer A-buffer
475f9031 1015 (goto-char (if shift-A shift-A (point-min))))
e756eb9f 1016 (ediff-with-current-buffer B-buffer
475f9031 1017 (goto-char (if shift-B shift-B (point-min))))
4ad42cb5 1018 (if three-way-comp
e756eb9f 1019 (ediff-with-current-buffer C-buffer
4ad42cb5
MK
1020 (goto-char (if shift-C shift-C (point-min)))))
1021 (if (ediff-buffer-live-p anc-buffer)
e756eb9f 1022 (ediff-with-current-buffer anc-buffer
4ad42cb5 1023 (goto-char (point-min))))
71296446 1024
e756eb9f 1025 (ediff-with-current-buffer diff-buffer
475f9031
KH
1026 (goto-char (point-min))
1027 (while (re-search-forward ediff-match-diff3-line nil t)
1028 ;; leave point after matched line
1029 (beginning-of-line 2)
1030 (let ((agreement (buffer-substring (match-beginning 1) (match-end 1))))
bbe6126c 1031 ;; if the files A and B are the same and not 3way-comparison,
475f9031
KH
1032 ;; ignore the difference
1033 (if (or three-way-comp (not (string-equal agreement "3")))
1034 (let* ((a-begin (car (ediff-get-diff3-group "1")))
1035 (a-end (nth 1 (ediff-get-diff3-group "1")))
1036 (b-begin (car (ediff-get-diff3-group "2")))
1037 (b-end (nth 1 (ediff-get-diff3-group "2")))
4ad42cb5
MK
1038 (c-or-anc-begin (car (ediff-get-diff3-group "3")))
1039 (c-or-anc-end (nth 1 (ediff-get-diff3-group "3")))
475f9031
KH
1040 (state-of-merge
1041 (cond ((string-equal agreement "1") 'prefer-A)
1042 ((string-equal agreement "2") 'prefer-B)
1043 (t ediff-default-variant)))
1044 (state-of-diff-merge
1045 (if (memq state-of-merge '(default-A prefer-A)) 'B 'A))
1046 (state-of-diff-comparison
1047 (cond ((string-equal agreement "1") 'A)
1048 ((string-equal agreement "2") 'B)
1049 ((string-equal agreement "3") 'C)))
4ad42cb5 1050 state-of-ancestor
475f9031
KH
1051 c-begin c-end
1052 a-begin-pt a-end-pt
4ad42cb5
MK
1053 b-begin-pt b-end-pt
1054 c-begin-pt c-end-pt
1055 anc-begin-pt anc-end-pt)
71296446 1056
4ad42cb5
MK
1057 (setq state-of-ancestor
1058 (= c-or-anc-begin c-or-anc-end))
1059
1060 (cond (three-way-comp
1061 (setq c-begin c-or-anc-begin
1062 c-end c-or-anc-end))
1063 ((eq ediff-default-variant 'default-B)
1064 (setq c-begin b-begin
1065 c-end b-end))
1066 (t
1067 (setq c-begin a-begin
1068 c-end a-end)))
71296446 1069
475f9031
KH
1070 ;; compute main diff vector
1071 (if word-mode
1072 ;; make diff-list contain word numbers
50a07e18 1073 (setq diff-list
475f9031
KH
1074 (nconc diff-list
1075 (list (vector
1076 (- a-begin a-prev) (- a-end a-begin)
1077 (- b-begin b-prev) (- b-end b-begin)
1078 (- c-begin c-prev) (- c-end c-begin)
4ad42cb5
MK
1079 nil nil ; dummy ancestor
1080 nil ; state of diff
1081 nil ; state of merge
1082 nil ; state of ancestor
1083 )))
475f9031
KH
1084 a-prev a-end
1085 b-prev b-end
1086 c-prev c-end)
1087 ;; else convert lines to points
e756eb9f 1088 (ediff-with-current-buffer A-buffer
8ea74b0e
MK
1089 (let ((longlines-mode-val
1090 (if (and (boundp 'longlines-mode) longlines-mode) 1 0)))
1091 ;; we must disable and then restore longlines-mode
1092 (if (eq longlines-mode-val 1)
1093 (longlines-mode 0))
b6178721 1094 (goto-char (or a-prev-pt shift-A (point-min)))
8ea74b0e
MK
1095 (forward-line (- a-begin a-prev))
1096 (setq a-begin-pt (point))
1097 (forward-line (- a-end a-begin))
1098 (setq a-end-pt (point)
b6178721
MK
1099 a-prev a-end
1100 a-prev-pt a-end-pt)
8ea74b0e
MK
1101 (if (eq longlines-mode-val 1)
1102 (longlines-mode longlines-mode-val))
1103 ))
e756eb9f 1104 (ediff-with-current-buffer B-buffer
8ea74b0e
MK
1105 (let ((longlines-mode-val
1106 (if (and (boundp 'longlines-mode) longlines-mode) 1 0)))
1107 (if (eq longlines-mode-val 1)
1108 (longlines-mode 0))
b6178721 1109 (goto-char (or b-prev-pt shift-B (point-min)))
8ea74b0e
MK
1110 (forward-line (- b-begin b-prev))
1111 (setq b-begin-pt (point))
1112 (forward-line (- b-end b-begin))
1113 (setq b-end-pt (point)
b6178721
MK
1114 b-prev b-end
1115 b-prev-pt b-end-pt)
8ea74b0e
MK
1116 (if (eq longlines-mode-val 1)
1117 (longlines-mode longlines-mode-val))
1118 ))
e756eb9f 1119 (ediff-with-current-buffer C-buffer
8ea74b0e
MK
1120 (let ((longlines-mode-val
1121 (if (and (boundp 'longlines-mode) longlines-mode) 1 0)))
1122 (if (eq longlines-mode-val 1)
1123 (longlines-mode 0))
b6178721 1124 (goto-char (or c-prev-pt shift-C (point-min)))
8ea74b0e
MK
1125 (forward-line (- c-begin c-prev))
1126 (setq c-begin-pt (point))
1127 (forward-line (- c-end c-begin))
1128 (setq c-end-pt (point)
b6178721
MK
1129 c-prev c-end
1130 c-prev-pt c-end-pt)
8ea74b0e
MK
1131 (if (eq longlines-mode-val 1)
1132 (longlines-mode longlines-mode-val))
1133 ))
4ad42cb5 1134 (if (ediff-buffer-live-p anc-buffer)
e756eb9f 1135 (ediff-with-current-buffer anc-buffer
8ea74b0e
MK
1136 (let ((longlines-mode-val
1137 (if (and (boundp 'longlines-mode) longlines-mode) 1 0)))
1138 (if (eq longlines-mode-val 1)
1139 (longlines-mode 0))
1140 (forward-line (- c-or-anc-begin anc-prev))
1141 (setq anc-begin-pt (point))
1142 (forward-line (- c-or-anc-end c-or-anc-begin))
1143 (setq anc-end-pt (point)
1144 anc-prev c-or-anc-end)
1145 (if (eq longlines-mode-val 1)
1146 (longlines-mode longlines-mode-val))
1147 )))
50a07e18 1148 (setq diff-list
475f9031
KH
1149 (nconc
1150 diff-list
1151 ;; if comparing with ancestor, then there also is a
1152 ;; state-of-difference marker
1153 (if three-way-comp
1154 (list (vector
1155 a-begin-pt a-end-pt
1156 b-begin-pt b-end-pt
1157 c-begin-pt c-end-pt
4ad42cb5 1158 nil nil ; ancestor begin/end
475f9031 1159 state-of-diff-comparison
4ad42cb5
MK
1160 nil ; state of merge
1161 nil ; state of ancestor
475f9031
KH
1162 ))
1163 (list (vector a-begin-pt a-end-pt
1164 b-begin-pt b-end-pt
1165 c-begin-pt c-end-pt
4ad42cb5 1166 anc-begin-pt anc-end-pt
475f9031
KH
1167 state-of-diff-merge
1168 state-of-merge
4ad42cb5 1169 state-of-ancestor
475f9031
KH
1170 )))
1171 )))
1172 ))
71296446 1173
e756eb9f 1174 ))) ; end ediff-with-current-buffer
475f9031
KH
1175 diff-list
1176 ))
71296446 1177
475f9031
KH
1178;; Generate the difference vector and overlays for three files
1179;; File-C is either the third file to compare (in case of 3-way comparison)
1180;; or it is the ancestor file.
1181(defun ediff-setup-diff-regions3 (file-A file-B file-C)
b6178721 1182 ;; looking for '-i' or a 'i' among clustered non-long options
608c89a9 1183 (if (string-match "^-i\\| -i\\|\\(^\\| \\)-[^- ]+i" ediff-diff-options)
b6178721
MK
1184 (error "Option `-i' is not allowed in `ediff-diff3-options'"))
1185
475f9031
KH
1186 (or (ediff-buffer-live-p ediff-diff-buffer)
1187 (setq ediff-diff-buffer
1188 (get-buffer-create (ediff-unique-buffer-name "*ediff-diff" "*"))))
71296446 1189
4ad42cb5
MK
1190 (message "Computing differences ...")
1191 (ediff-exec-process ediff-diff3-program ediff-diff-buffer 'synchronize
b6178721 1192 ediff-actual-diff3-options file-A file-B file-C)
71296446 1193
475f9031 1194 (ediff-prepare-error-list ediff-diff3-ok-lines-regexp ediff-diff-buffer)
4ad42cb5 1195 ;;(message "Computing differences ... done")
475f9031
KH
1196 (ediff-convert-diffs-to-overlays
1197 (ediff-extract-diffs3
1198 ediff-diff-buffer
1199 ediff-word-mode ediff-3way-comparison-job ediff-narrow-bounds)
1200 ))
71296446 1201
475f9031 1202
4ae69eac 1203;; Execute PROGRAM asynchronously, unless OS/2, Windows-*, or DOS, or unless
e756eb9f
MK
1204;; SYNCH is non-nil. BUFFER must be a buffer object, and must be alive. The
1205;; OPTIONS arg is a list of options to pass to PROGRAM. It may be a blank
1206;; string. All elements in FILES must be strings. We also delete nil from
1207;; args.
1208(defun ediff-exec-process (program buffer synch options &rest files)
1209 (let ((data (match-data))
95aac6d1
EZ
1210 ;; If this is a buffer job, we are diffing temporary files
1211 ;; produced by Emacs with ediff-coding-system-for-write, so
1212 ;; use the same encoding to read the results.
1213 (coding-system-for-read
1214 (if (string-match "buffer" (symbol-name ediff-job-name))
1215 ediff-coding-system-for-write
1216 ediff-coding-system-for-read))
e756eb9f
MK
1217 args)
1218 (setq args (append (split-string options) files))
1219 (setq args (delete "" (delq nil args))) ; delete nil and "" from arguments
7997f1ca 1220 ;; the --binary option, if present, should be used only for buffer jobs
560ef11a 1221 ;; or for refining the differences
7997f1ca 1222 (or (string-match "buffer" (symbol-name ediff-job-name))
560ef11a 1223 (eq buffer ediff-fine-diff-buffer)
7997f1ca 1224 (setq args (delete "--binary" args)))
475f9031
KH
1225 (unwind-protect
1226 (let ((directory default-directory)
1227 proc)
475f9031
KH
1228 (save-excursion
1229 (set-buffer buffer)
1230 (erase-buffer)
1231 (setq default-directory directory)
4ae69eac
MK
1232 (if (or (memq system-type '(emx ms-dos windows-nt windows-95))
1233 synch)
1234 ;; In OS/2 (emx) do it synchronously, since OS/2 doesn't let us
4ad42cb5
MK
1235 ;; delete files used by other processes. Thus, in ediff-buffers
1236 ;; and similar functions, we can't delete temp files because
4ae69eac 1237 ;; they might be used by the asynch process that computes
4ad42cb5
MK
1238 ;; custom diffs. So, we have to wait till custom diff
1239 ;; subprocess is done.
4ae69eac
MK
1240 ;; Similarly for Windows-*
1241 ;; In DOS, must synchronize because DOS doesn't have
1242 ;; asynchronous processes.
31e71026 1243 (apply 'call-process program nil buffer nil args)
4ad42cb5
MK
1244 ;; On other systems, do it asynchronously.
1245 (setq proc (get-buffer-process buffer))
1246 (if proc (kill-process proc))
1247 (setq proc
1248 (apply 'start-process "Custom Diff" buffer program args))
1249 (setq mode-line-process '(":%s"))
1250 (set-process-sentinel proc 'ediff-process-sentinel)
1251 (set-process-filter proc 'ediff-process-filter)
1252 )))
2eb4bdca 1253 (store-match-data data))))
71296446 1254
863312cd 1255;; This is shell-command-filter from simple.el in Emacs.
475f9031 1256;; Copied here because XEmacs doesn't have it.
4ad42cb5 1257(defun ediff-process-filter (proc string)
475f9031
KH
1258 ;; Do save-excursion by hand so that we can leave point numerically unchanged
1259 ;; despite an insertion immediately after it.
1260 (let* ((obuf (current-buffer))
1261 (buffer (process-buffer proc))
1262 opoint
1263 (window (get-buffer-window buffer))
1264 (pos (window-start window)))
1265 (unwind-protect
1266 (progn
1267 (set-buffer buffer)
1268 (or (= (point) (point-max))
1269 (setq opoint (point)))
1270 (goto-char (point-max))
1271 (insert-before-markers string))
1272 ;; insert-before-markers moved this marker: set it back.
1273 (set-window-start window pos)
1274 ;; Finish our save-excursion.
1275 (if opoint
1276 (goto-char opoint))
1277 (set-buffer obuf))))
71296446 1278
475f9031
KH
1279;; like shell-command-sentinel but doesn't print an exit status message
1280;; we do this because diff always exits with status 1, if diffs are found
1281;; so shell-command-sentinel displays a confusing message to the user
4ad42cb5 1282(defun ediff-process-sentinel (process signal)
475f9031
KH
1283 (if (and (memq (process-status process) '(exit signal))
1284 (buffer-name (process-buffer process)))
1285 (progn
1286 (save-excursion
1287 (set-buffer (process-buffer process))
1288 (setq mode-line-process nil))
1289 (delete-process process))))
71296446 1290
475f9031 1291
50a07e18 1292;;; Word functions used to refine the current diff
475f9031
KH
1293
1294(defvar ediff-forward-word-function 'ediff-forward-word
1295 "*Function to call to move to the next word.
1296Used for splitting difference regions into individual words.")
743a79af 1297(make-variable-buffer-local 'ediff-forward-word-function)
475f9031 1298
ec6aebe8
MK
1299;; \240 is unicode symbol for nonbreakable whitespace
1300(defvar ediff-whitespace " \n\t\f\r\240"
475f9031
KH
1301 "*Characters constituting white space.
1302These characters are ignored when differing regions are split into words.")
743a79af 1303(make-variable-buffer-local 'ediff-whitespace)
475f9031 1304
50a07e18 1305(defvar ediff-word-1
dc3fbc6a 1306 (if (featurep 'xemacs) "a-zA-Z---_" "-[:word:]_")
475f9031
KH
1307 "*Characters that constitute words of type 1.
1308More precisely, [ediff-word-1] is a regexp that matches type 1 words.
50a07e18 1309See `ediff-forward-word' for more details.")
743a79af 1310(make-variable-buffer-local 'ediff-word-1)
475f9031
KH
1311
1312(defvar ediff-word-2 "0-9.,"
1313 "*Characters that constitute words of type 2.
1314More precisely, [ediff-word-2] is a regexp that matches type 2 words.
1315See `ediff-forward-word' for more details.")
743a79af 1316(make-variable-buffer-local 'ediff-word-2)
475f9031
KH
1317
1318(defvar ediff-word-3 "`'?!:;\"{}[]()"
1319 "*Characters that constitute words of type 3.
1320More precisely, [ediff-word-3] is a regexp that matches type 3 words.
1321See `ediff-forward-word' for more details.")
743a79af 1322(make-variable-buffer-local 'ediff-word-3)
475f9031
KH
1323
1324(defvar ediff-word-4
1325 (concat "^" ediff-word-1 ediff-word-2 ediff-word-3 ediff-whitespace)
1326 "*Characters that constitute words of type 4.
1327More precisely, [ediff-word-4] is a regexp that matches type 4 words.
50a07e18 1328See `ediff-forward-word' for more details.")
743a79af 1329(make-variable-buffer-local 'ediff-word-4)
475f9031
KH
1330
1331;; Split region along word boundaries. Each word will be on its own line.
1332;; Output to buffer out-buffer.
1333(defun ediff-forward-word ()
1334 "Move point one word forward.
1335There are four types of words, each of which consists entirely of
1336characters in `ediff-word-1', `ediff-word-2', `ediff-word-3', or
6de3983f
MK
1337`ediff-word-4'. Words are recognized by passing these one after another as
1338arguments to `skip-chars-forward'."
1339 (or (> (+ (skip-chars-forward ediff-word-1)
1340 (skip-syntax-forward "w"))
1341 0)
475f9031
KH
1342 (> (skip-chars-forward ediff-word-2) 0)
1343 (> (skip-chars-forward ediff-word-3) 0)
1344 (> (skip-chars-forward ediff-word-4) 0)
1345 ))
1346
d396e521 1347
475f9031 1348(defun ediff-wordify (beg end in-buffer out-buffer &optional control-buf)
50a07e18
MK
1349 (let ((forward-word-function
1350 ;; eval in control buf to let user create local versions for
1351 ;; different invocations
1352 (if control-buf
1353 (ediff-with-current-buffer control-buf
1354 ediff-forward-word-function)
1355 ediff-forward-word-function))
1356 inbuf-syntax-tbl sv-point diff-string)
475f9031
KH
1357 (save-excursion
1358 (set-buffer in-buffer)
4986c2c6
MK
1359 (setq inbuf-syntax-tbl
1360 (if control-buf
1361 (ediff-with-current-buffer control-buf
1362 ediff-syntax-table)
1363 (syntax-table)))
1364 (setq diff-string (buffer-substring-no-properties beg end))
475f9031
KH
1365
1366 (set-buffer out-buffer)
4696802b 1367 ;; Make sure that temp buff syntax table is the same as the original buf
d396e521
MK
1368 ;; syntax tbl, because we use ediff-forward-word in both and
1369 ;; ediff-forward-word depends on the syntax classes of characters.
1370 (set-syntax-table inbuf-syntax-tbl)
475f9031 1371 (erase-buffer)
4986c2c6 1372 (insert diff-string)
475f9031
KH
1373 (goto-char (point-min))
1374 (skip-chars-forward ediff-whitespace)
1375 (delete-region (point-min) (point))
71296446 1376
475f9031 1377 (while (not (eobp))
50a07e18 1378 (funcall forward-word-function)
475f9031
KH
1379 (setq sv-point (point))
1380 (skip-chars-forward ediff-whitespace)
1381 (delete-region sv-point (point))
1382 (insert "\n")))))
71296446 1383
50a07e18 1384;; copy string specified as BEG END from IN-BUF to OUT-BUF
475f9031 1385(defun ediff-copy-to-buffer (beg end in-buffer out-buffer)
50a07e18
MK
1386 (with-current-buffer out-buffer
1387 (erase-buffer)
1388 (insert-buffer-substring in-buffer beg end)
1389 (goto-char (point-min))))
475f9031
KH
1390
1391
1392;; goto word #n starting at current position in buffer `buf'
4986c2c6 1393;; For ediff, a word is determined by ediff-forward-word-function
475f9031
KH
1394;; If `flag' is non-nil, goto the end of the n-th word.
1395(defun ediff-goto-word (n buf &optional flag)
1396 ;; remember val ediff-forward-word-function has in ctl buf
4986c2c6
MK
1397 (let ((fwd-word-fun ediff-forward-word-function)
1398 (syntax-tbl ediff-syntax-table))
e756eb9f 1399 (ediff-with-current-buffer buf
475f9031 1400 (skip-chars-forward ediff-whitespace)
50a07e18
MK
1401 (ediff-with-syntax-table syntax-tbl
1402 (while (> n 1)
1403 (funcall fwd-word-fun)
1404 (skip-chars-forward ediff-whitespace)
17561e4f
MK
1405 (setq n (1- n)))
1406 (if (and flag (> n 0))
1407 (funcall fwd-word-fun)))
475f9031
KH
1408 (point))))
1409
328b4b70 1410(defun ediff-same-file-contents (f1 f2)
17561e4f
MK
1411 "Return t if files F1 and F2 have identical contents."
1412 (if (and (not (file-directory-p f1))
1413 (not (file-directory-p f2)))
31e71026
MK
1414 (let ((res
1415 (apply 'call-process ediff-cmp-program nil nil nil
1416 (append ediff-cmp-options (list (expand-file-name f1)
1417 (expand-file-name f2))))
1418 ))
1419 (and (numberp res) (eq res 0)))
ec6aebe8 1420 ))
17561e4f
MK
1421
1422
1423(defun ediff-same-contents (d1 d2 &optional filter-re)
4837b516 1424 "Return t if D1 and D2 have the same content.
17561e4f
MK
1425D1 and D2 can either be both directories or both regular files.
1426Symlinks and the likes are not handled.
1427If FILTER-RE is non-nil, recursive checking in directories
1428affects only files whose names match the expression."
1429 ;; Normalize empty filter RE to nil.
899a431b 1430 (unless (> (length filter-re) 0) (setq filter-re nil))
17561e4f
MK
1431 ;; Indicate progress
1432 (message "Comparing '%s' and '%s' modulo '%s'" d1 d2 filter-re)
1433 (cond
1434 ;; D1 & D2 directories => recurse
1435 ((and (file-directory-p d1)
1436 (file-directory-p d2))
1437 (if (null ediff-recurse-to-subdirectories)
1438 (if (y-or-n-p "Compare subdirectories recursively? ")
1439 (setq ediff-recurse-to-subdirectories 'yes)
1440 (setq ediff-recurse-to-subdirectories 'no)))
1441 (if (eq ediff-recurse-to-subdirectories 'yes)
1442 (let* ((all-entries-1 (directory-files d1 t filter-re))
1443 (all-entries-2 (directory-files d2 t filter-re))
899a431b
MK
1444 (entries-1 (ediff-delete-all-matches "^\\.\\.?$" all-entries-1))
1445 (entries-2 (ediff-delete-all-matches "^\\.\\.?$" all-entries-2))
17561e4f 1446 )
899a431b
MK
1447
1448 (ediff-same-file-contents-lists entries-1 entries-2 filter-re)
17561e4f
MK
1449 ))
1450 ) ; end of the directories case
1451 ;; D1 & D2 are both files => compare directly
1452 ((and (file-regular-p d1)
1453 (file-regular-p d2))
1454 (ediff-same-file-contents d1 d2))
1455 ;; Otherwise => false: unequal contents
1456 )
1457 )
328b4b70 1458
899a431b
MK
1459;; If lists have the same length and names of files are pairwise equal
1460;; (removing the directories) then compare contents pairwise.
1461;; True if all contents are the same; false otherwise
1462(defun ediff-same-file-contents-lists (entries-1 entries-2 filter-re)
1463 ;; First, check only the names (works quickly and ensures a
1464 ;; precondition for subsequent code)
1465 (if (and (= (length entries-1) (length entries-2))
1466 (equal (mapcar 'file-name-nondirectory entries-1)
1467 (mapcar 'file-name-nondirectory entries-2)))
1468 ;; With name equality established, compare the entries
1469 ;; through recursion.
1470 (let ((continue t))
1471 (while (and entries-1 continue)
1472 (if (ediff-same-contents
1473 (car entries-1) (car entries-2) filter-re)
1474 (setq entries-1 (cdr entries-1)
1475 entries-2 (cdr entries-2))
1476 (setq continue nil))
1477 )
1478 ;; if reached the end then lists are equal
1479 (null entries-1))
1480 )
1481 )
1482
1483
1484;; ARG1 is a regexp, ARG2 is a list of full-filenames
1485;; Delete all entries that match the regexp
1486(defun ediff-delete-all-matches (regex file-list-list)
1487 (let (result elt)
1488 (while file-list-list
1489 (setq elt (car file-list-list))
1490 (or (string-match regex (file-name-nondirectory elt))
1491 (setq result (cons elt result)))
1492 (setq file-list-list (cdr file-list-list)))
1493 (reverse result)))
1494
ec6aebe8
MK
1495
1496(defun ediff-set-actual-diff-options ()
1497 (if ediff-ignore-case
36ba07ae 1498 (setq ediff-actual-diff-options
ec6aebe8
MK
1499 (concat ediff-diff-options " " ediff-ignore-case-option)
1500 ediff-actual-diff3-options
1501 (concat ediff-diff3-options " " ediff-ignore-case-option3))
1502 (setq ediff-actual-diff-options ediff-diff-options
1503 ediff-actual-diff3-options ediff-diff3-options)
1504 )
1505 (setq-default ediff-actual-diff-options ediff-actual-diff-options
1506 ediff-actual-diff3-options ediff-actual-diff3-options)
1507 )
1508
1509
b6178721
MK
1510;; Ignore case handling - some ideas from drew.adams@@oracle.com
1511(defun ediff-toggle-ignore-case ()
1512 (interactive)
1513 (ediff-barf-if-not-control-buffer)
1514 (setq ediff-ignore-case (not ediff-ignore-case))
ec6aebe8
MK
1515 (ediff-set-actual-diff-options)
1516 (if ediff-ignore-case
1517 (message "Ignoring regions that differ only in case")
1518 (message "Ignoring case differences turned OFF"))
b6178721
MK
1519 (cond (ediff-merge-job
1520 (message "Ignoring letter case is too dangerous in merge jobs"))
1521 ((and ediff-diff3-job (string= ediff-ignore-case-option3 ""))
1522 (message "Ignoring letter case is not supported by this diff3 program"))
1523 ((and (not ediff-3way-job) (string= ediff-ignore-case-option ""))
1524 (message "Ignoring letter case is not supported by this diff program"))
1525 (t
1526 (sit-for 1)
1527 (ediff-update-diffs)))
1528 )
1529
1530
475f9031 1531
bbe6126c
MK
1532;;; Local Variables:
1533;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun)
e756eb9f
MK
1534;;; eval: (put 'ediff-with-current-buffer 'lisp-indent-hook 1)
1535;;; eval: (put 'ediff-with-current-buffer 'edebug-form-spec '(form body))
bbe6126c
MK
1536;;; End:
1537
cbee283d 1538;; arch-tag: a86d448e-58d7-4572-a1d9-fdedfa22f648
3afbc435 1539;;; ediff-diff.el ends here