(rmail-output-file-alist): Add autoload cookie.
[bpt/emacs.git] / lisp / ediff-init.el
CommitLineData
8343426b 1;;; ediff-init.el --- Macros, variables, and defsubsts used by Ediff
b578f267 2
bbe6126c 3;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
475f9031
KH
4
5;; Author: Michael Kifer <kifer@cs.sunysb.edu>
6
7;; This file is part of GNU Emacs.
8
9;; GNU Emacs is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
b578f267
EN
20;; along with GNU Emacs; see the file COPYING. If not, write to the
21;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
475f9031 23
b578f267 24;;; Code:
475f9031 25
bbe6126c
MK
26;; Start compiler pacifier
27(defvar ediff-metajob-name)
28(defvar ediff-meta-buffer)
29(defvar pm-color-alist)
30(defvar ediff-grab-mouse)
31(defvar ediff-mouse-pixel-position)
32(defvar ediff-mouse-pixel-threshold)
33(defvar ediff-whitespace)
34(defvar ediff-multiframe)
35;; end pacifier
36
41d25ad0 37;; Is it XEmacs?
8343426b 38(defconst ediff-xemacs-p (string-match "XEmacs" emacs-version))
41d25ad0
KH
39;; Is it Emacs?
40(defconst ediff-emacs-p (not ediff-xemacs-p))
bbe6126c
MK
41
42(defvar ediff-force-faces nil
43 "If t, Ediff will think that it is running on a display that supports faces.
44This is provided as a temporary relief for users of face-capable displays
45that Ediff doesn't know about.")
46
41d25ad0
KH
47;; Are we running as a window application or on a TTY?
48(defsubst ediff-device-type ()
49 (if ediff-emacs-p
50 window-system
51 (device-type (selected-device))))
bbe6126c 52
41d25ad0 53;; in XEmacs: device-type is tty on tty and stream in batch.
4ae69eac
MK
54(defun ediff-window-display-p ()
55 (and (ediff-device-type) (not (memq (ediff-device-type) '(tty pc stream)))))
56
57;; test if supports faces
58;; ediff-force-faces is for those devices that support faces, but we don't know
59;; this yet
60(defun ediff-has-face-support-p ()
61 (cond ((ediff-window-display-p))
62 (ediff-force-faces)
63 (ediff-emacs-p (memq (ediff-device-type) '(pc)))
64 (ediff-xemacs-p (memq (ediff-device-type) '(tty pc)))))
65
bbe6126c
MK
66
67;; Defines SYMBOL as an advertised local variable.
68;; Performs a defvar, then executes `make-variable-buffer-local' on
69;; the variable. Also sets the `permanent-local' property,
70;; so that `kill-all-local-variables' (called by major-mode setting
71;; commands) won't destroy Ediff control variables.
72;;
73;; Plagiarised from `emerge-defvar-local' for XEmacs.
74(defmacro ediff-defvar-local (var value doc)
75 (` (progn
76 (defvar (, var) (, value) (, doc))
77 (make-variable-buffer-local '(, var))
78 (put '(, var) 'permanent-local t))))
79
80
81
82;; Variables that control each Ediff session---local to the control buffer.
83
84;; Mode variables
85;; The buffer in which the A variant is stored.
86(ediff-defvar-local ediff-buffer-A nil "")
87;; The buffer in which the B variant is stored.
88(ediff-defvar-local ediff-buffer-B nil "")
89;; The buffer in which the C variant is stored.
90(ediff-defvar-local ediff-buffer-C nil "")
91;; Ancestor buffer
92(ediff-defvar-local ediff-ancestor-buffer nil "")
93;; The control buffer of ediff.
94(ediff-defvar-local ediff-control-buffer nil "")
475f9031
KH
95
96;;; Macros
97(defmacro ediff-odd-p (arg)
98 (` (eq (logand (, arg) 1) 1)))
99
100(defmacro ediff-buffer-live-p (buf)
101 (` (and (, buf) (get-buffer (, buf)) (buffer-name (get-buffer (, buf))))))
102
103(defmacro ediff-get-buffer (arg)
104 (` (cond ((eq (, arg) 'A) ediff-buffer-A)
105 ((eq (, arg) 'B) ediff-buffer-B)
106 ((eq (, arg) 'C) ediff-buffer-C)
8343426b 107 ((eq (, arg) 'Ancestor) ediff-ancestor-buffer)
475f9031
KH
108 )
109 ))
110
111(defmacro ediff-get-value-according-to-buffer-type (buf-type list)
112 (` (cond ((eq (, buf-type) 'A) (nth 0 (, list)))
113 ((eq (, buf-type) 'B) (nth 1 (, list)))
114 ((eq (, buf-type) 'C) (nth 2 (, list))))))
115
116(defmacro ediff-char-to-buftype (arg)
117 (` (cond ((memq (, arg) '(?a ?A)) 'A)
118 ((memq (, arg) '(?b ?B)) 'B)
119 ((memq (, arg) '(?c ?C)) 'C)
120 )
121 ))
122
123(defmacro ediff-get-difference (n buf-type)
124 (` (aref
125 (symbol-value
126 (intern (format "ediff-difference-vector-%S" (, buf-type)))) (, n))))
127
128;; tell if it has been previously determined that the region has
129;; no diffs other than the white space and newlines
130;; The argument, N, is the diff region number used by Ediff to index the
131;; diff vector. It is 1 less than the number seen by the user.
132;;
133;; A difference vector has the form:
134;; [diff diff diff ...]
135;; where each diff has the form:
136;; [overlay fine-diff-vector no-fine-diffs-flag]
137;; fine-diff-vector is a vector [fine-diff fine-diff fine-diff ...]
138(defmacro ediff-no-fine-diffs-p (n)
139 (` (aref (ediff-get-difference (, n) 'A) 2)))
140
141(defmacro ediff-get-diff-overlay-from-diff-record (diff-rec)
142 (` (aref (, diff-rec) 0)))
143
144(defmacro ediff-get-diff-overlay (n buf-type)
145 (` (ediff-get-diff-overlay-from-diff-record
146 (ediff-get-difference (, n) (, buf-type)))))
147
148(defmacro ediff-get-fine-diff-vector-from-diff-record (diff-rec)
149 (` (aref (, diff-rec) 1)))
150
151(defmacro ediff-set-fine-diff-vector (n buf-type fine-vec)
152 (` (aset (ediff-get-difference (, n) (, buf-type)) 1 (, fine-vec))))
153
154(defmacro ediff-get-state-of-diff (n buf-type)
155 (` (if (ediff-buffer-live-p ediff-buffer-C)
156 (aref (ediff-get-difference (, n) (, buf-type)) 3))))
157(defmacro ediff-set-state-of-diff (n buf-type val)
158 (` (aset (ediff-get-difference (, n) (, buf-type)) 3 (, val))))
159(defmacro ediff-get-state-of-merge (n)
8343426b
MK
160 (` (if ediff-state-of-merge
161 (aref (aref ediff-state-of-merge (, n)) 0))))
162(defmacro ediff-get-state-of-ancestor (n)
163 (` (if ediff-state-of-merge
164 (aref (aref ediff-state-of-merge (, n)) 1))))
475f9031 165(defmacro ediff-set-state-of-merge (n val)
8343426b
MK
166 (` (if ediff-state-of-merge
167 (aset (aref ediff-state-of-merge (, n)) 0 (, val)))))
475f9031
KH
168
169;; if flag is t, puts a mark on diff region saying that
170;; the differences are in white space only. If flag is nil,
171;; the region is marked as essential (i.e., differences are
172;; not just in the white space and newlines.)
173(defmacro ediff-mark-diff-as-space-only (n flag)
174 (` (aset (ediff-get-difference (, n) 'A) 2 (, flag))))
175
176(defmacro ediff-get-fine-diff-vector (n buf-type)
177 (` (ediff-get-fine-diff-vector-from-diff-record
178 (ediff-get-difference (, n) (, buf-type)))))
179
475f9031
KH
180;; Macro to switch to BUFFER, evaluate FORMS, returns to original buffer.
181;; Differs from `save-excursion' in that it doesn't save the point and mark.
182;; This is essentially `emerge-eval-in-buffer' with the test for live buffers."
183(defmacro ediff-eval-in-buffer (buffer &rest forms)
184 (` (let ((StartBuffer (current-buffer)))
185 (if (ediff-buffer-live-p (, buffer))
186 (unwind-protect
187 (progn
188 (set-buffer (, buffer))
189 (,@ forms))
190 (set-buffer StartBuffer))
191 (or (eq this-command 'ediff-quit)
4ae69eac 192 (error ediff-KILLED-VITAL-BUFFER))
475f9031
KH
193 ))))
194
cca9c6fc
RS
195(put 'ediff-eval-in-buffer 'lisp-indent-function 1)
196(put 'ediff-eval-in-buffer 'lisp-indent-hook 1)
197(put 'ediff-eval-in-buffer 'edebug-form-spec '(form body))
198
475f9031 199
8343426b
MK
200(defsubst ediff-multiframe-setup-p ()
201 (and (ediff-window-display-p) ediff-multiframe))
475f9031
KH
202
203(defmacro ediff-narrow-control-frame-p ()
204 (` (and (ediff-multiframe-setup-p)
205 (equal ediff-help-message ediff-brief-message-string))))
206
207(defmacro ediff-3way-comparison-job ()
208 (` (memq
209 ediff-job-name
210 '(ediff-files3 ediff-buffers3))))
211(ediff-defvar-local ediff-3way-comparison-job nil "")
212
213(defmacro ediff-merge-job ()
214 (` (memq
215 ediff-job-name
216 '(ediff-merge-files
217 ediff-merge-buffers
218 ediff-merge-files-with-ancestor
219 ediff-merge-buffers-with-ancestor
220 ediff-merge-revisions
221 ediff-merge-revisions-with-ancestor))))
222(ediff-defvar-local ediff-merge-job nil "")
223
224(defmacro ediff-merge-with-ancestor-job ()
225 (` (memq
226 ediff-job-name
227 '(ediff-merge-files-with-ancestor
228 ediff-merge-buffers-with-ancestor
229 ediff-merge-revisions-with-ancestor))))
230(ediff-defvar-local ediff-merge-with-ancestor-job nil "")
231
232(defmacro ediff-3way-job ()
233 (` (or ediff-3way-comparison-job ediff-merge-job)))
234(ediff-defvar-local ediff-3way-job nil "")
235
236;; A diff3 job is like a 3way job, but ediff-merge doesn't require the use
237;; of diff3.
238(defmacro ediff-diff3-job ()
239 (` (or ediff-3way-comparison-job
240 ediff-merge-with-ancestor-job)))
241(ediff-defvar-local ediff-diff3-job nil "")
242
41d25ad0
KH
243(defmacro ediff-windows-job ()
244 (` (memq ediff-job-name '(ediff-windows-wordwise ediff-windows-linewise))))
245(ediff-defvar-local ediff-windows-job nil "")
246
475f9031 247(defmacro ediff-word-mode-job ()
41d25ad0 248 (` (memq ediff-job-name '(ediff-windows-wordwise ediff-regions-wordwise))))
475f9031
KH
249(ediff-defvar-local ediff-word-mode-job nil "")
250
41d25ad0
KH
251(defmacro ediff-narrow-job ()
252 (` (memq ediff-job-name '(ediff-windows-wordwise
253 ediff-regions-wordwise
254 ediff-windows-linewise
255 ediff-regions-linewise))))
256(ediff-defvar-local ediff-narrow-job nil "")
257
8343426b
MK
258;; Note: ediff-merge-directory-revisions-with-ancestor is not treated as an
259;; ancestor metajob, since it behaves differently.
260(defsubst ediff-ancestor-metajob (&optional metajob)
261 (memq (or metajob ediff-metajob-name)
262 '(ediff-merge-directories-with-ancestor
263 ediff-merge-filegroups-with-ancestor)))
264(defsubst ediff-revision-metajob (&optional metajob)
265 (memq (or metajob ediff-metajob-name)
266 '(ediff-directory-revisions
267 ediff-merge-directory-revisions
268 ediff-merge-directory-revisions-with-ancestor)))
bbe6126c
MK
269(defsubst ediff-patch-metajob (&optional metajob)
270 (memq (or metajob ediff-metajob-name)
271 '(ediff-multifile-patch)))
272;; metajob involving only one group of files, such as multipatch or directory
273;; revision
274(defsubst ediff-one-filegroup-metajob (&optional metajob)
8343426b 275 (or (ediff-revision-metajob metajob)
bbe6126c 276 (ediff-patch-metajob metajob)
8343426b
MK
277 ;; add more here
278 ))
279(defsubst ediff-collect-diffs-metajob (&optional metajob)
4ae69eac
MK
280 (memq (or metajob ediff-metajob-name)
281 '(ediff-directories
282 ediff-directory-revisions
283 ediff-merge-directories
284 ediff-merge-directories-with-ancestor
285 ediff-merge-directory-revisions
286 ediff-merge-directory-revisions-with-ancestor
287 ;; add more here
288 )))
289
8343426b
MK
290(defsubst ediff-metajob3 (&optional metajob)
291 (memq (or metajob ediff-metajob-name)
292 '(ediff-merge-directories-with-ancestor
293 ediff-merge-filegroups-with-ancestor
294 ediff-directories3
295 ediff-filegroups3)))
296(defsubst ediff-comparison-metajob3 (&optional metajob)
297 (memq (or metajob ediff-metajob-name)
298 '(ediff-directories3 ediff-filegroups3)))
299
300(defsubst ediff-barf-if-not-control-buffer (&optional meta-buf)
301 (or (eq (if meta-buf ediff-meta-buffer ediff-control-buffer)
302 (current-buffer))
303 (error "%S: This command runs in Ediff Control Buffer only!"
304 this-command)))
305
475f9031
KH
306
307;; Hook variables
308
8343426b
MK
309(defvar ediff-before-setup-windows-hook nil
310 "*Hooks to run before Ediff sets its window configuration.
475f9031
KH
311This can be used to save the previous window config, which can be restored
312on ediff-quit or ediff-suspend.")
8343426b
MK
313(defvar ediff-after-setup-windows-hook nil
314 "*Hooks to run after Ediff sets its window configuration.
475f9031 315This can be used to set up control window or icon in a desired place.")
8343426b 316(defvar ediff-before-setup-control-frame-hook nil
475f9031
KH
317 "*Hooks run before setting up the frame to display Ediff Control Panel.
318Can be used to change control frame parameters to position it where it
319is desirable.")
8343426b 320(defvar ediff-after-setup-control-frame-hook nil
475f9031
KH
321 "*Hooks run after setting up the frame to display Ediff Control Panel.
322Can be used to move the frame where it is desired.")
8343426b 323(defvar ediff-startup-hook nil
475f9031 324 "*Hooks to run in the control buffer after Ediff has been set up.")
8343426b 325(defvar ediff-select-hook nil
475f9031 326 "*Hooks to run after a difference has been selected.")
8343426b 327(defvar ediff-unselect-hook nil
475f9031 328 "*Hooks to run after a difference has been unselected.")
8343426b 329(defvar ediff-prepare-buffer-hook nil
475f9031 330 "*Hooks called after buffers A, B, and C are set up.")
8343426b 331(defvar ediff-load-hook nil
475f9031
KH
332 "*Hook run after Ediff is loaded. Can be used to change defaults.")
333
8343426b 334(defvar ediff-mode-hook nil
475f9031
KH
335 "*Hook run just after ediff-mode is set up in the control buffer.
336This is done before any windows or frames are created. One can use it to
337set local variables that determine how the display looks like.")
8343426b 338(defvar ediff-keymap-setup-hook nil
475f9031
KH
339 "*Hook run just after the default bindings in Ediff keymap are set up.")
340
8343426b 341(defvar ediff-display-help-hook nil
475f9031
KH
342 "*Hooks run after preparing the help message.")
343
8343426b 344(defvar ediff-suspend-hook (list 'ediff-default-suspend-function)
475f9031 345 "*Hooks to run in the Ediff control buffer when Ediff is suspended.")
8343426b 346(defvar ediff-quit-hook (list 'ediff-cleanup-mess)
475f9031 347 "*Hooks to run in the Ediff control buffer after finishing Ediff.")
8343426b 348(defvar ediff-cleanup-hook nil
41d25ad0
KH
349 "*Hooks to run on exiting Ediff but before killing the control buffer.
350This is a place to do various cleanups, such as deleting the variant buffers.
351Ediff provides a function, `ediff-janitor', as one such possible hook.")
475f9031
KH
352
353
354;; Help messages
355
356(defconst ediff-long-help-message-head
357 " Moving around | Toggling features | Manipulations
358=====================|===========================|============================="
359 "The head of the full help message.")
360(defconst ediff-long-help-message-tail
361 "=====================|===========================|=============================
8343426b
MK
362 R -show registry | | M -show session group
363 D -diff output | E -browse Ediff manual| G -send bug report
364 i -status info | ? -help off | z/q -suspend/quit
475f9031
KH
365-------------------------------------------------------------------------------
366X,Y (x,y) on the left are meta-symbols for the keys A,B,C (a,b,c).
367X,Y on the right are meta-symbols for buffers A,B,C.
368A,B,C on the right denote the working buffers A,B,C, respectively."
369 "The tail of the full-help message.")
370
371(defconst ediff-long-help-message-compare3
372 "
373p,DEL -previous diff | | -vert/horiz split | xy -copy buf X's region to Y
374n,SPC -next diff | h -hiliting | rx -restore buf X's old diff
375 j -jump to diff | @ -auto-refinement | * -refine current region
376 gx -goto X's point| | ! -update diff regions
377 C-l -recenter | ## -ignore whitespace |
378 v/V -scroll up/dn | #f/#h -focus/hide regions | wx -save buf X
379 </> -scroll lt/rt | X -read-only in buf X | wd -save diff output
8343426b 380 | m -wide display | ~ -rotate buffers
475f9031 381"
41d25ad0
KH
382 "Help message usually used for 3-way comparison.
383Normally, not a user option. See `ediff-help-message' for details.")
475f9031
KH
384
385(defconst ediff-long-help-message-compare2
386 "
387p,DEL -previous diff | | -vert/horiz split |a/b -copy A/B's region to B/A
388n,SPC -next diff | h -hiliting | rx -restore buf X's old diff
389 j -jump to diff | @ -auto-refinement | * -refine current region
390 gx -goto X's point| | ! -update diff regions
391 C-l -recenter | ## -ignore whitespace |
392 v/V -scroll up/dn | #f/#h -focus/hide regions | wx -save buf X
393 </> -scroll lt/rt | X -read-only in buf X | wd -save diff output
4ae69eac 394 ~ -swap variants | m -wide display |
475f9031 395"
41d25ad0
KH
396 "Help message usually used for 2-way comparison.
397Normally, not a user option. See `ediff-help-message' for details.")
398
399(defconst ediff-long-help-message-narrow2
400 "
401p,DEL -previous diff | | -vert/horiz split |a/b -copy A/B's region to B/A
402n,SPC -next diff | h -hiliting | rx -restore buf X's old diff
403 j -jump to diff | @ -auto-refinement | * -refine current region
404 gx -goto X's point| % -narrow/widen buffs | ! -update diff regions
405 C-l -recenter | ## -ignore whitespace |
406 v/V -scroll up/dn | #f/#h -focus/hide regions | wx -save buf X
407 </> -scroll lt/rt | X -read-only in buf X | wd -save diff output
4ae69eac 408 ~ -swap variants | m -wide display |
41d25ad0
KH
409"
410 "Help message when comparing windows or regions line-by-line.
411Normally, not a user option. See `ediff-help-message' for details.")
475f9031
KH
412
413(defconst ediff-long-help-message-word-mode
414 "
415p,DEL -previous diff | | -vert/horiz split | xy -copy buf X's region to Y
416n,SPC -next diff | h -hiliting | rx -restore buf X's old diff
417 j -jump to diff | |
418 gx -goto X's point| % -narrow/widen buffs | ! -recompute diffs
419 C-l -recenter | |
420 v/V -scroll up/dn | #f/#h -focus/hide regions | wx -save buf X
421 </> -scroll lt/rt | X -read-only in buf X | wd -save diff output
4ae69eac 422 ~ -swap variants | m -wide display |
475f9031 423"
41d25ad0
KH
424 "Help message when comparing windows or regions word-by-word.
425Normally, not a user option. See `ediff-help-message' for details.")
475f9031
KH
426
427(defconst ediff-long-help-message-merge
428 "
429p,DEL -previous diff | | -vert/horiz split | x -copy buf X's region to C
430n,SPC -next diff | h -hiliting | r -restore buf C's old diff
431 j -jump to diff | @ -auto-refinement | * -refine current region
432 gx -goto X's point| ## -ignore whitespace | ! -update diff regions
433 C-l -recenter | #f/#h -focus/hide regions | + -combine diff regions
434 v/V -scroll up/dn | X -read-only in buf X | wx -save buf X
435 </> -scroll lt/rt | m -wide display | wd -save diff output
4ae69eac 436 ~ -swap variants | s -shrink window C | / -show ancestor buff
475f9031
KH
437 | $ -show clashes only | & -merge w/new default
438"
41d25ad0
KH
439 "Help message during merging.
440Normally, not a user option. See `ediff-help-message' for details.")
475f9031
KH
441
442;; The actual long help message.
443(ediff-defvar-local ediff-long-help-message ""
444 "Normally, not a user option. See `ediff-help-message' for details.")
445
446(defconst ediff-brief-message-string
447 " ? - help "
448 "Contents of the brief help message.")
449;; The actual brief help message
450(ediff-defvar-local ediff-brief-help-message ""
451 "Normally, not a user option. See `ediff-help-message' for details.")
452
8343426b 453(ediff-defvar-local ediff-brief-help-message-function nil
475f9031
KH
454 "The brief help message that the user can customize.
455If the user sets this to a parameter-less function, Ediff will use it to
456produce the brief help message. This function must return a string.")
8343426b 457(ediff-defvar-local ediff-long-help-message-function nil
475f9031 458 "The long help message that the user can customize.
8343426b 459See `ediff-brief-help-message-function' for more.")
475f9031 460
4ae69eac
MK
461(defvar ediff-use-long-help-message nil
462 "*If t, Ediff displays a long help message. Short help message otherwise.")
475f9031
KH
463
464;; The actual help message.
465(ediff-defvar-local ediff-help-message ""
466 "The actual help message.
467Normally, the user shouldn't touch this. However, if you want Ediff to
468start up with different help messages for different jobs, you can change
469the value of this variable and the variables `ediff-help-message-*' in
8343426b 470`ediff-startup-hook'.")
4ae69eac
MK
471
472;; Error messages
473(defconst ediff-KILLED-VITAL-BUFFER
474 "You have killed a vital Ediff buffer---you must leave Ediff now!")
475(defconst ediff-NO-DIFFERENCES
bbe6126c
MK
476 "Sorry, comparison of identical variants is not what I am made for...")
477(defconst ediff-BAD-DIFF-NUMBER
478 ;; %S stands for this-command, %d - diff number, %d - max diff
479 "%S: Bad diff region number, %d. Valid numbers are 1 to %d")
475f9031
KH
480
481;; Selective browsing
482
483(ediff-defvar-local ediff-skip-diff-region-function 'ediff-show-all-diffs
484 "Function that determines the next/previous diff region to show.
485Should return t for regions to be ignored and nil otherwise.
486This function gets a region number as an argument. The region number
487is the one used internally by Ediff. It is 1 less than the number seen
488by the user.")
489
8343426b
MK
490(ediff-defvar-local ediff-hide-regexp-matches-function
491 'ediff-hide-regexp-matches
492 "Function to use in determining which regions to hide.
493See the documentation string of `ediff-hide-regexp-matches' for details.")
494(ediff-defvar-local ediff-focus-on-regexp-matches-function
495 'ediff-focus-on-regexp-matches
496 "Function to use in determining which regions to focus on.
497See the documentation string of `ediff-focus-on-regexp-matches' for details.")
498
475f9031
KH
499;; Regexp that determines buf A regions to focus on when skipping to diff
500(ediff-defvar-local ediff-regexp-focus-A "" "")
501;; Regexp that determines buf B regions to focus on when skipping to diff
502(ediff-defvar-local ediff-regexp-focus-B "" "")
503;; Regexp that determines buf C regions to focus on when skipping to diff
504(ediff-defvar-local ediff-regexp-focus-C "" "")
505;; connective that determines whether to focus regions that match both or
506;; one of the regexps
507(ediff-defvar-local ediff-focus-regexp-connective 'and "")
508
509;; Regexp that determines buf A regions to ignore when skipping to diff
510(ediff-defvar-local ediff-regexp-hide-A "" "")
511;; Regexp that determines buf B regions to ignore when skipping to diff
512(ediff-defvar-local ediff-regexp-hide-B "" "")
513;; Regexp that determines buf C regions to ignore when skipping to diff
514(ediff-defvar-local ediff-regexp-hide-C "" "")
515;; connective that determines whether to hide regions that match both or
516;; one of the regexps
517(ediff-defvar-local ediff-hide-regexp-connective 'and "")
518
519
520(defvar ediff-ange-ftp-ftp-name (if ediff-xemacs-p
521 'ange-ftp-ftp-path
522 'ange-ftp-ftp-name)
523 "Function ange-ftp uses to find out if file is remote.")
524
525
526;; Copying difference regions between buffers.
527(ediff-defvar-local ediff-killed-diffs-alist nil
528 "A list of killed diffs.
529A diff is saved here if it is replaced by a diff
530from another buffer. This alist has the form:
531\((num (buff-object . diff) (buff-object . diff) (buff-object . diff)) ...),
532where some buffer-objects may be missing.")
533
534
535;; Highlighting
41d25ad0
KH
536;;(defvar ediff-before-flag-bol (if ediff-emacs-p "->>\n" (make-glyph "->>\n"))
537(defvar ediff-before-flag-bol (if ediff-xemacs-p (make-glyph "->>") "->>")
475f9031
KH
538 "*Flag placed above the highlighted block of differences.
539Must end with newline.")
41d25ad0
KH
540;;(defvar ediff-after-flag-eol (if ediff-emacs-p "<<-\n" (make-glyph "<<-"))
541(defvar ediff-after-flag-eol (if ediff-xemacs-p (make-glyph "<<-") "<<-")
475f9031
KH
542 "*Flag placed below the highlighted block of differences.
543Must end with newline.")
544
41d25ad0 545(defvar ediff-before-flag-mol (if ediff-xemacs-p (make-glyph "->>") "->>")
475f9031 546 "*Like ediff-before-flag, used when a difference starts in mid-line.")
41d25ad0 547(defvar ediff-after-flag-mol (if ediff-xemacs-p (make-glyph "<<-") "<<-")
475f9031
KH
548 "*Like ediff-after-flag, used when a difference starts in mid-line.")
549
475f9031
KH
550
551(ediff-defvar-local ediff-use-faces t
4ae69eac
MK
552 "If t, differences are highlighted using faces, if device supports faces.
553If nil, differences are highlighted using ASCII flags, ediff-before-flag
475f9031
KH
554and ediff-after-flag. On a non-window system, differences are always
555highlighted using ASCII flags.
556This variable can be set either in .emacs or toggled interactively.
557Use `setq-default' if setting it in .emacs")
558
475f9031 559;; this indicates that diff regions are word-size, so fine diffs are
41d25ad0 560;; permanently nixed; used in ediff-windows-wordwise and ediff-regions-wordwise
475f9031 561(ediff-defvar-local ediff-word-mode nil "")
8343426b 562;; Name of the job (ediff-files, ediff-windows, etc.)
475f9031
KH
563(ediff-defvar-local ediff-job-name nil "")
564
565;; Narrowing and ediff-region/windows support
566;; This is a list (overlay-A overlay-B overlay-C)
567;; If set, Ediff compares only those parts of buffers A/B/C that lie within
568;; the bounds of these overlays.
569(ediff-defvar-local ediff-narrow-bounds nil "")
570
571;; List (overlay-A overlay-B overlay-C), where each overlay spans the
572;; entire corresponding buffer.
573(ediff-defvar-local ediff-wide-bounds nil "")
574
575;; Current visibility boundaries in buffers A, B, and C.
576;; This is also a list of overlays. When the user toggles narrow/widen,
577;; this list changes from ediff-wide-bounds to ediff-narrow-bounds.
578;; and back.
579(ediff-defvar-local ediff-visible-bounds nil "")
580
581(ediff-defvar-local ediff-start-narrowed t
41d25ad0 582 "Non-nil means start narrowed, if doing ediff-windows-* or ediff-regions-*")
475f9031
KH
583(ediff-defvar-local ediff-quit-widened t
584 "*Non-nil means: when finished, Ediff widens buffers A/B.
585Actually, Ediff restores the scope of visibility that existed at startup.")
8343426b
MK
586(defvar ediff-keep-variants t
587 "*Nil means that non-modified variant buffers should be removed after some
588interrogation.
ceb0ea8b 589Supplying a prefix argument to the quit command `q' temporarily reverses the
8343426b 590meaning of this variable.")
475f9031
KH
591
592(ediff-defvar-local ediff-highlight-all-diffs t
593 "If nil, only the selected differences are highlighted.
594This variable can be set either in .emacs or toggled interactively, using
595ediff-toggle-hilit. Use `setq-default' to set it.")
596
597;; A var local to each control panel buffer. Indicates highlighting style
598;; in effect for this buffer: `face', `ascii', nil -- temporarily
599;; unhighlighted, `off' -- turned off \(on a dumb terminal only\).
600(ediff-defvar-local ediff-highlighting-style nil "")
601
475f9031
KH
602
603;; The suffix of the control buffer name.
604(ediff-defvar-local ediff-control-buffer-suffix nil "")
605;; Same as ediff-control-buffer-suffix, but without <,>.
606;; It's a number rather than string.
607(ediff-defvar-local ediff-control-buffer-number nil "")
608
609
475f9031 610;; The original values of ediff-protected-variables for buffer A
41d25ad0 611(ediff-defvar-local ediff-buffer-values-orig-A nil "")
475f9031 612;; The original values of ediff-protected-variables for buffer B
41d25ad0 613(ediff-defvar-local ediff-buffer-values-orig-B nil "")
475f9031 614;; The original values of ediff-protected-variables for buffer C
41d25ad0 615(ediff-defvar-local ediff-buffer-values-orig-C nil "")
8343426b
MK
616;; The original values of ediff-protected-variables for buffer Ancestor
617(ediff-defvar-local ediff-buffer-values-orig-Ancestor nil "")
618;; Buffer-local variables to be saved then restored during Ediff sessions
475f9031
KH
619;; Buffer-local variables to be saved then restored during Ediff sessions
620(defconst ediff-protected-variables '(buffer-read-only
4ae69eac 621;;; synchronize-minibuffers
475f9031
KH
622 mode-line-format))
623
475f9031
KH
624;; Vector of differences between the variants. Each difference is
625;; represented by a vector of two overlays plus a vector of fine diffs,
626;; plus a no-fine-diffs flag. The first overlay spans the
627;; difference region in the A buffer and the second overlays the diff in
628;; the B buffer. If a difference section is empty, the corresponding
629;; overlay's endpoints coincide.
630;;
631;; The precise form of a difference vector for one buffer is:
632;; [diff diff diff ...]
633;; where each diff has the form:
8343426b 634;; [diff-overlay fine-diff-vector no-fine-diffs-flag state-of-difference]
475f9031
KH
635;; fine-diff-vector is a vector [fine-diff-overlay fine-diff-overlay ...]
636;; no-fine-diffs-flag says if there are fine differences.
637;; state-of-difference is A, B, C, or nil, indicating which buffer is
638;; different from the other two (used only in 3-way jobs.
475f9031
KH
639(ediff-defvar-local ediff-difference-vector-A nil "")
640(ediff-defvar-local ediff-difference-vector-B nil "")
641(ediff-defvar-local ediff-difference-vector-C nil "")
8343426b
MK
642(ediff-defvar-local ediff-difference-vector-Ancestor nil "")
643
644;; [ status status status ...]
645;; Each status: [state-of-merge state-of-ancestor]
646;; state-of-merge is default-A, default-B, prefer-A, or prefer-B. It
647;; indicates the way a diff region was created in buffer C.
648;; state-of-ancestor says if the corresponding region in ancestor buffer is
649;; empty.
650(ediff-defvar-local ediff-state-of-merge nil "")
475f9031
KH
651
652;; The difference that is currently selected.
653(ediff-defvar-local ediff-current-difference -1 "")
654;; Number of differences found.
655(ediff-defvar-local ediff-number-of-differences nil "")
656
657;; Buffer containing the output of diff, which is used by Ediff to step
658;; through files.
659(ediff-defvar-local ediff-diff-buffer nil "")
660;; Like ediff-diff-buffer, but contains context diff. It is not used by
661;; Ediff, but it is saved in a file, if user requests so.
662(ediff-defvar-local ediff-custom-diff-buffer nil "")
663;; Buffer used for diff-style fine differences between regions.
664(ediff-defvar-local ediff-fine-diff-buffer nil "")
665;; Temporary buffer used for computing fine differences.
666(defconst ediff-tmp-buffer " *ediff-tmp*" "")
667;; Buffer used for messages
668(defconst ediff-msg-buffer " *ediff-message*" "")
669;; Buffer containing the output of diff when diff returns errors.
670(ediff-defvar-local ediff-error-buffer nil "")
671;; Buffer to display debug info
672(ediff-defvar-local ediff-debug-buffer "*ediff-debug*" "")
673
8343426b
MK
674;; List of ediff control panels associated with each buffer A/B/C/Ancestor.
675;; Not used any more, but may be needed in the future.
676(ediff-defvar-local ediff-this-buffer-ediff-sessions nil "")
475f9031
KH
677
678;; to be deleted in due time
679;; List of difference overlays disturbed by working with the current diff.
680(defvar ediff-disturbed-overlays nil "")
681
682;; Priority of non-selected overlays.
683(defvar ediff-shadow-overlay-priority 100 "")
684
8343426b
MK
685(defvar ediff-version-control-package 'vc
686 "Version control package used.
4ae69eac
MK
687Currently, Ediff supports vc.el, rcs.el, pcl-cvs.el, and generic-sc.el. The
688standard Emacs interface to RCS, CVS, SCCS, etc., is vc.el. However, some
689people find the other two packages more convenient. Set this variable to the
690appropriate symbol: `rcs', `pcl-cvs', or `generic-sc' if you so desire.")
8343426b 691
475f9031
KH
692
693(if ediff-xemacs-p
694 (progn
695 (fset 'ediff-read-event (symbol-function 'next-command-event))
696 (fset 'ediff-overlayp (symbol-function 'extentp))
697 (fset 'ediff-make-overlay (symbol-function 'make-extent))
4ae69eac 698 (fset 'ediff-delete-overlay (symbol-function 'delete-extent)))
475f9031
KH
699 (fset 'ediff-read-event (symbol-function 'read-event))
700 (fset 'ediff-overlayp (symbol-function 'overlayp))
41d25ad0 701 (fset 'ediff-overlayp (symbol-function 'overlayp))
475f9031 702 (fset 'ediff-make-overlay (symbol-function 'make-overlay))
4ae69eac 703 (fset 'ediff-delete-overlay (symbol-function 'delete-overlay)))
475f9031 704
41d25ad0
KH
705;; Check the current version against the major and minor version numbers
706;; using op: cur-vers op major.minor If emacs-major-version or
707;; emacs-minor-version are not defined, we assume that the current version
708;; is hopelessly outdated. We assume that emacs-major-version and
709;; emacs-minor-version are defined. Otherwise, for Emacs/XEmacs 19, if the
710;; current minor version is < 10 (xemacs) or < 23 (emacs) the return value
711;; will be nil (when op is =, >, or >=) and t (when op is <, <=), which may be
712;; incorrect. However, this gives correct result in our cases, since we are
713;; testing for sufficiently high Emacs versions.
714(defun ediff-check-version (op major minor &optional type-of-emacs)
715 (if (and (boundp 'emacs-major-version) (boundp 'emacs-minor-version))
716 (and (cond ((eq type-of-emacs 'xemacs) ediff-xemacs-p)
717 ((eq type-of-emacs 'emacs) ediff-emacs-p)
718 (t t))
719 (cond ((eq op '=) (and (= emacs-minor-version minor)
720 (= emacs-major-version major)))
721 ((memq op '(> >= < <=))
722 (and (or (funcall op emacs-major-version major)
723 (= emacs-major-version major))
724 (if (= emacs-major-version major)
725 (funcall op emacs-minor-version minor)
726 t)))
727 (t
728 (error "%S: Invalid op in ediff-check-version" op))))
729 (cond ((memq op '(= > >=)) nil)
730 ((memq op '(< <=)) t))))
731
8343426b
MK
732
733;;;; warn if it is a wrong version of emacs
734;;(if (or (ediff-check-version '< 19 29 'emacs)
735;; (ediff-check-version '< 19 12 'xemacs))
736;; (progn
737;; (with-output-to-temp-buffer ediff-msg-buffer
738;; (switch-to-buffer ediff-msg-buffer)
739;; (insert
740;; (format "
741;;
742;;This version of Ediff requires
743;;
744;;\t Emacs 19.29 and higher
745;;\t OR
746;;\t XEmacs 19.12 and higher
747;;
748;;It is unlikely to work under Emacs version %s
749;;that you are using... " emacs-version))
750;; (if noninteractive
751;; ()
752;; (beep 1)
753;; (beep 1)
754;; (insert "\n\nType any key to continue...")
755;; (ediff-read-event)))
756;; (kill-buffer ediff-msg-buffer)))
757
475f9031
KH
758;; A fix for NeXT Step
759;; Should probably be eliminated in later versions.
41d25ad0 760(if (and (ediff-window-display-p) (eq (ediff-device-type) 'ns))
475f9031
KH
761 (progn
762 (fset 'x-display-color-p (symbol-function 'ns-display-color-p))
763 (fset 'x-color-defined-p (symbol-function 'ns-color-defined-p))
764 (fset 'x-display-pixel-height (symbol-function 'ns-display-pixel-height))
765 (fset 'x-display-pixel-width (symbol-function 'ns-display-pixel-width))
766 ))
41d25ad0 767
8343426b 768
41d25ad0
KH
769(defsubst ediff-color-display-p ()
770 (if ediff-emacs-p
771 (x-display-color-p)
772 (eq (device-class (selected-device)) 'color)))
8343426b 773
475f9031 774
4ae69eac 775(if (ediff-has-face-support-p)
41d25ad0
KH
776 (if ediff-xemacs-p
777 (progn
41d25ad0
KH
778 (fset 'ediff-valid-color-p (symbol-function 'valid-color-name-p))
779 (fset 'ediff-get-face (symbol-function 'get-face)))
780 ;; Temporary fix for OS/2 port of Emacs
781 ;; pm-win.el in PM-Emacs should be fixed.
41d25ad0
KH
782 (if (eq (ediff-device-type) 'pm)
783 (fset 'ediff-valid-color-p
784 (function (lambda (color) (assoc color pm-color-alist))))
785 (fset 'ediff-valid-color-p (symbol-function 'x-color-defined-p)))
786 (fset 'ediff-get-face (symbol-function 'internal-get-face))))
4ae69eac
MK
787
788(if (ediff-window-display-p)
789 (if ediff-xemacs-p
790 (progn
791 (fset 'ediff-display-pixel-width
792 (symbol-function 'device-pixel-width))
793 (fset 'ediff-display-pixel-height
794 (symbol-function 'device-pixel-height)))
795 (fset 'ediff-display-pixel-width
796 (symbol-function 'x-display-pixel-width))
797 (fset 'ediff-display-pixel-height
798 (symbol-function 'x-display-pixel-height))))
475f9031 799
475f9031 800
8343426b 801(defun ediff-make-current-diff-overlay (type)
4ae69eac 802 (if (ediff-has-face-support-p)
8343426b
MK
803 (let ((overlay (intern (format "ediff-current-diff-overlay-%S" type)))
804 (buffer (ediff-get-buffer type))
805 (face (face-name
806 (symbol-value
807 (intern (format "ediff-current-diff-face-%S" type))))))
808 (set overlay
809 (ediff-make-bullet-proof-overlay (point-max) (point-max) buffer))
810 (ediff-set-overlay-face (symbol-value overlay) face)
811 (ediff-overlay-put (symbol-value overlay) 'ediff ediff-control-buffer))
812 ))
813
814(defun ediff-set-overlay-face (extent face)
815 (ediff-overlay-put extent 'face face)
816 (ediff-overlay-put extent 'help-echo 'ediff-region-help-echo))
817
818;; This does nothing in Emacs, since overlays there have no help-echo property
819(defun ediff-region-help-echo (extent)
820 (let ((is-current (ediff-overlay-get extent 'ediff))
821 (face (ediff-overlay-get extent 'face))
822 (diff-num (ediff-overlay-get extent 'ediff-diff-num))
bbe6126c 823 face-help)
8343426b
MK
824
825 ;; This happens only for refinement overlays
826 (setq face-help (and face (get face 'ediff-help-echo)))
827
bbe6126c
MK
828 (cond ((and is-current diff-num) ; current diff region
829 (format "Difference region %S -- current" (1+ diff-num)))
830 (face-help) ; refinement of current diff region
831 (diff-num ; non-current
832 (format "Difference region %S -- non-current" (1+ diff-num)))
833 (t "")) ; none
834 ))
8343426b
MK
835
836(defun ediff-set-face (ground face color)
837 "Set face foreground/background."
4ae69eac 838 (if (ediff-has-face-support-p)
8343426b
MK
839 (if (ediff-valid-color-p color)
840 (if (eq ground 'foreground)
841 (set-face-foreground face color)
842 (set-face-background face color))
843 (cond ((memq face
844 '(ediff-current-diff-face-A
845 ediff-current-diff-face-B
846 ediff-current-diff-face-C
847 ediff-current-diff-face-Ancestor))
848 (copy-face 'highlight face))
849 ((memq face
850 '(ediff-fine-diff-face-A
851 ediff-fine-diff-face-B
852 ediff-fine-diff-face-C
853 ediff-fine-diff-face-Ancestor))
854 (copy-face 'secondary-selection face)
855 (set-face-underline-p face t))
856 ((memq face
857 '(ediff-even-diff-face-A
858 ediff-odd-diff-face-A
859 ediff-even-diff-face-B ediff-odd-diff-face-B
860 ediff-even-diff-face-C ediff-odd-diff-face-C
861 ediff-even-diff-face-Ancestor
862 ediff-odd-diff-face-Ancestor))
863 (copy-face 'secondary-selection face))))
864 ))
36d57fa9 865
4ae69eac
MK
866(defun ediff-hide-face (face)
867 (if (and (ediff-has-face-support-p) ediff-emacs-p)
868 (add-to-list 'facemenu-unlisted-faces face)))
869
8343426b 870(defvar ediff-current-diff-face-A
4ae69eac 871 (if (ediff-has-face-support-p)
8343426b
MK
872 (progn
873 (make-face 'ediff-current-diff-face-A)
4ae69eac 874 (ediff-hide-face 'ediff-current-diff-face-A)
8343426b
MK
875 (or (face-differs-from-default-p 'ediff-current-diff-face-A)
876 (cond ((ediff-color-display-p)
877 (ediff-set-face
878 'foreground 'ediff-current-diff-face-A "firebrick")
879 (ediff-set-face
880 'background 'ediff-current-diff-face-A "pale green"))
881 (t
882 (if ediff-xemacs-p
883 (copy-face 'modeline 'ediff-current-diff-face-A)
884 (copy-face 'highlight 'ediff-current-diff-face-A))
885 )))
886 'ediff-current-diff-face-A))
887 "Face for highlighting the selected difference in buffer A.")
888
889(defvar ediff-current-diff-face-B
4ae69eac 890 (if (ediff-has-face-support-p)
8343426b
MK
891 (progn
892 (make-face 'ediff-current-diff-face-B)
4ae69eac 893 (ediff-hide-face 'ediff-current-diff-face-B)
8343426b
MK
894 (or (face-differs-from-default-p 'ediff-current-diff-face-B)
895 (cond ((ediff-color-display-p)
896 (ediff-set-face
897 'foreground 'ediff-current-diff-face-B "DarkOrchid")
898 (ediff-set-face
899 'background 'ediff-current-diff-face-B "Yellow"))
900 (t
901 (if ediff-xemacs-p
902 (copy-face 'modeline 'ediff-current-diff-face-B)
903 (copy-face 'highlight 'ediff-current-diff-face-B))
904 )))
905 'ediff-current-diff-face-B))
906 "Face for highlighting the selected difference in buffer B.")
475f9031
KH
907
908
8343426b 909(defvar ediff-current-diff-face-C
4ae69eac 910 (if (ediff-has-face-support-p)
8343426b
MK
911 (progn
912 (make-face 'ediff-current-diff-face-C)
4ae69eac 913 (ediff-hide-face 'ediff-current-diff-face-C)
8343426b
MK
914 (or (face-differs-from-default-p 'ediff-current-diff-face-C)
915 (cond ((ediff-color-display-p)
916 (ediff-set-face
917 'foreground 'ediff-current-diff-face-C "Navy")
918 (ediff-set-face
919 'background 'ediff-current-diff-face-C "Pink"))
920 (t
921 (if ediff-xemacs-p
922 (copy-face 'modeline 'ediff-current-diff-face-C)
923 (copy-face 'highlight 'ediff-current-diff-face-C))
924 )))
925 'ediff-current-diff-face-C))
926 "Face for highlighting the selected difference in buffer C.")
927
928(defvar ediff-current-diff-face-Ancestor
4ae69eac 929 (if (ediff-has-face-support-p)
8343426b
MK
930 (progn
931 (make-face 'ediff-current-diff-face-Ancestor)
4ae69eac 932 (ediff-hide-face 'ediff-current-diff-face-Ancestor)
8343426b
MK
933 (or (face-differs-from-default-p 'ediff-current-diff-face-Ancestor)
934 (copy-face
935 'ediff-current-diff-face-C 'ediff-current-diff-face-Ancestor))))
936 "Face for highlighting the selected difference in the ancestor buffer.")
937
938(defvar ediff-fine-diff-face-A
4ae69eac 939 (if (ediff-has-face-support-p)
8343426b
MK
940 (progn
941 (make-face 'ediff-fine-diff-face-A)
4ae69eac 942 (ediff-hide-face 'ediff-fine-diff-face-A)
8343426b
MK
943 (or (face-differs-from-default-p 'ediff-fine-diff-face-A)
944 (cond ((ediff-color-display-p)
945 (ediff-set-face 'foreground 'ediff-fine-diff-face-A
946 "Navy")
947 (ediff-set-face 'background 'ediff-fine-diff-face-A
948 "sky blue"))
949 (t (set-face-underline-p 'ediff-fine-diff-face-A t))))
950 'ediff-fine-diff-face-A))
951 "Face for highlighting the refinement of the selected diff in buffer A.")
952
953(defvar ediff-fine-diff-face-B
4ae69eac 954 (if (ediff-has-face-support-p)
8343426b
MK
955 (progn
956 (make-face 'ediff-fine-diff-face-B)
4ae69eac 957 (ediff-hide-face 'ediff-fine-diff-face-B)
8343426b
MK
958 (or (face-differs-from-default-p 'ediff-fine-diff-face-B)
959 (cond ((ediff-color-display-p)
960 (ediff-set-face 'foreground 'ediff-fine-diff-face-B "Black")
961 (ediff-set-face 'background 'ediff-fine-diff-face-B "cyan"))
962 (t (set-face-underline-p 'ediff-fine-diff-face-B t))))
963 'ediff-fine-diff-face-B))
964 "Face for highlighting the refinement of the selected diff in buffer B.")
475f9031 965
8343426b 966(defvar ediff-fine-diff-face-C
4ae69eac 967 (if (ediff-has-face-support-p)
8343426b
MK
968 (progn
969 (make-face 'ediff-fine-diff-face-C)
4ae69eac 970 (ediff-hide-face 'ediff-fine-diff-face-C)
8343426b
MK
971 (or (face-differs-from-default-p 'ediff-fine-diff-face-C)
972 (cond ((ediff-color-display-p)
973 (ediff-set-face 'foreground 'ediff-fine-diff-face-C "black")
974 (ediff-set-face
975 'background 'ediff-fine-diff-face-C "Turquoise"))
976 (t (set-face-underline-p 'ediff-fine-diff-face-C t))))
977 'ediff-fine-diff-face-C))
978 "Face for highlighting the refinement of the selected diff in buffer C.")
979
980(defvar ediff-fine-diff-face-Ancestor
4ae69eac 981 (if (ediff-has-face-support-p)
8343426b
MK
982 (progn
983 (make-face 'ediff-fine-diff-face-Ancestor)
4ae69eac 984 (ediff-hide-face 'ediff-fine-diff-face-Ancestor)
8343426b
MK
985 (or (face-differs-from-default-p 'ediff-fine-diff-face-Ancestor)
986 (copy-face
987 'ediff-fine-diff-face-C 'ediff-fine-diff-face-Ancestor))))
988 "Face highlighting refinements of the selected diff in ancestor buffer.
989Presently, this is not used, as difference regions are not refined in the
990ancestor buffer.")
475f9031 991
8343426b 992(defvar ediff-even-diff-face-A
4ae69eac 993 (if (ediff-has-face-support-p)
8343426b
MK
994 (progn
995 (make-face 'ediff-even-diff-face-A)
4ae69eac 996 (ediff-hide-face 'ediff-even-diff-face-A)
8343426b
MK
997 (or (face-differs-from-default-p 'ediff-even-diff-face-A)
998 (cond ((ediff-color-display-p)
999 (ediff-set-face
1000 'foreground 'ediff-even-diff-face-A "black")
1001 (ediff-set-face
1002 'background 'ediff-even-diff-face-A "light grey"))
1003 (t
1004 (copy-face 'italic 'ediff-even-diff-face-A))))
1005 'ediff-even-diff-face-A))
1006 "Face used to highlight even-numbered differences in buffer A.")
475f9031 1007
8343426b 1008(defvar ediff-even-diff-face-B
4ae69eac 1009 (if (ediff-has-face-support-p)
8343426b
MK
1010 (progn
1011 (make-face 'ediff-even-diff-face-B)
4ae69eac 1012 (ediff-hide-face 'ediff-even-diff-face-B)
8343426b
MK
1013 (or (face-differs-from-default-p 'ediff-even-diff-face-B)
1014 (cond ((ediff-color-display-p)
1015 (ediff-set-face
1016 'foreground 'ediff-even-diff-face-B "White")
1017 (ediff-set-face
1018 'background 'ediff-even-diff-face-B "Gray"))
1019 (t
1020 (copy-face 'italic 'ediff-even-diff-face-B))))
1021 'ediff-even-diff-face-B))
1022 "Face used to highlight even-numbered differences in buffer B.")
475f9031 1023
8343426b 1024(defvar ediff-even-diff-face-C
4ae69eac 1025 (if (ediff-has-face-support-p)
8343426b
MK
1026 (progn
1027 (make-face 'ediff-even-diff-face-C)
4ae69eac 1028 (ediff-hide-face 'ediff-even-diff-face-C)
8343426b
MK
1029 (or (face-differs-from-default-p 'ediff-even-diff-face-C)
1030 (copy-face 'ediff-even-diff-face-A 'ediff-even-diff-face-C))
1031 'ediff-even-diff-face-C))
1032 "Face used to highlight even-numbered differences in buffer C.")
1033
1034(defvar ediff-even-diff-face-Ancestor
4ae69eac 1035 (if (ediff-has-face-support-p)
8343426b
MK
1036 (progn
1037 (make-face 'ediff-even-diff-face-Ancestor)
4ae69eac 1038 (ediff-hide-face 'ediff-even-diff-face-Ancestor)
8343426b
MK
1039 (or (face-differs-from-default-p 'ediff-even-diff-face-Ancestor)
1040 (copy-face 'ediff-even-diff-face-C 'ediff-even-diff-face-Ancestor))
1041 'ediff-even-diff-face-Ancestor))
1042 "Face highlighting even-numbered differences in the ancestor buffer.")
475f9031 1043
8343426b 1044(defvar ediff-odd-diff-face-A
4ae69eac 1045 (if (ediff-has-face-support-p)
8343426b
MK
1046 (progn
1047 (make-face 'ediff-odd-diff-face-A)
4ae69eac 1048 (ediff-hide-face 'ediff-odd-diff-face-A)
8343426b
MK
1049 (or (face-differs-from-default-p 'ediff-odd-diff-face-A)
1050 (cond ((ediff-color-display-p)
1051 (ediff-set-face
1052 'foreground 'ediff-odd-diff-face-A "White")
1053 (ediff-set-face
1054 'background 'ediff-odd-diff-face-A "Gray"))
1055 (t
1056 (copy-face 'italic 'ediff-odd-diff-face-A))))
1057 'ediff-odd-diff-face-A))
1058 "Face used to highlight odd-numbered differences in buffer A.")
475f9031 1059
8343426b 1060(defvar ediff-odd-diff-face-B
4ae69eac 1061 (if (ediff-has-face-support-p)
8343426b
MK
1062 (progn
1063 (make-face 'ediff-odd-diff-face-B)
4ae69eac 1064 (ediff-hide-face 'ediff-odd-diff-face-B)
8343426b
MK
1065 (or (face-differs-from-default-p 'ediff-odd-diff-face-B)
1066 (cond ((ediff-color-display-p)
1067 (ediff-set-face
1068 'foreground 'ediff-odd-diff-face-B "Black")
1069 (ediff-set-face
1070 'background 'ediff-odd-diff-face-B "light grey"))
1071 (t
1072 (copy-face 'italic 'ediff-odd-diff-face-B))))
1073 'ediff-odd-diff-face-B))
1074 "Face used to highlight odd-numbered differences in buffer B.")
475f9031 1075
8343426b 1076(defvar ediff-odd-diff-face-C
4ae69eac 1077 (if (ediff-has-face-support-p)
8343426b
MK
1078 (progn
1079 (make-face 'ediff-odd-diff-face-C)
4ae69eac 1080 (ediff-hide-face 'ediff-odd-diff-face-C)
8343426b
MK
1081 (or (face-differs-from-default-p 'ediff-odd-diff-face-C)
1082 (copy-face 'ediff-odd-diff-face-A 'ediff-odd-diff-face-C))
1083 'ediff-odd-diff-face-C))
1084 "Face used to highlight odd-numbered differences in buffer C.")
1085
1086(defvar ediff-odd-diff-face-Ancestor
4ae69eac 1087 (if (ediff-has-face-support-p)
8343426b
MK
1088 (progn
1089 (make-face 'ediff-odd-diff-face-Ancestor)
4ae69eac 1090 (ediff-hide-face 'ediff-odd-diff-face-Ancestor)
8343426b
MK
1091 (or (face-differs-from-default-p 'ediff-odd-diff-face-Ancestor)
1092 (copy-face 'ediff-odd-diff-face-C 'ediff-odd-diff-face-Ancestor))
1093 'ediff-odd-diff-face-Ancestor))
1094 "Face used to highlight even-numbered differences in the ancestor buffer.")
1095
1096;; Help echo
1097(put 'ediff-fine-diff-face-A 'ediff-help-echo
1098 "A `refinement' of the current difference region")
1099(put 'ediff-fine-diff-face-B 'ediff-help-echo
1100 "A `refinement' of the current difference region")
1101(put 'ediff-fine-diff-face-C 'ediff-help-echo
1102 "A `refinement' of the current difference region")
1103(put 'ediff-fine-diff-face-Ancestor 'ediff-help-echo
1104 "A `refinement' of the current difference region")
1105
475f9031
KH
1106
1107;;; Overlays
1108
8343426b
MK
1109(ediff-defvar-local ediff-current-diff-overlay-A nil
1110 "Overlay for the current difference region in buffer A.")
1111(ediff-defvar-local ediff-current-diff-overlay-B nil
1112 "Overlay for the current difference region in buffer B.")
1113(ediff-defvar-local ediff-current-diff-overlay-C nil
1114 "Overlay for the current difference region in buffer C.")
1115(ediff-defvar-local ediff-current-diff-overlay-Ancestor nil
1116 "Overlay for the current difference region in the ancestor buffer.")
475f9031 1117
8343426b
MK
1118;; Compute priority of ediff overlay.
1119(defun ediff-highest-priority (start end buffer)
1120 (let ((pos (max 1 (1- start)))
1121 ovr-list)
1122 (if ediff-xemacs-p
1123 (1+ ediff-shadow-overlay-priority)
1124 (ediff-eval-in-buffer buffer
1125 (while (< pos (min (point-max) (1+ end)))
1126 (setq ovr-list (append (overlays-at pos) ovr-list))
1127 (setq pos (next-overlay-change pos)))
1128 (1+ (apply '+
1129 (mapcar (function
1130 (lambda (ovr)
1131 (if ovr
1132 (or (ediff-overlay-get ovr 'priority) 0)
1133 0)))
1134 ovr-list)
1135 ))
1136 ))))
475f9031
KH
1137
1138
1139(defvar ediff-toggle-read-only-function nil
1140 "*Specifies the function to be used to toggle read-only.
1141If nil, Ediff tries to deduce the function from the binding of C-x C-q.
1142Normally, this is the `toggle-read-only' function, but, if version
1143control is used, it could be `vc-toggle-read-only' or `rcs-toggle-read-only'.")
1144
475f9031
KH
1145
1146;;; Misc
1147
475f9031
KH
1148;; if nil, this silences some messages
1149(defconst ediff-verbose-p t)
1150
1151(defvar ediff-no-emacs-help-in-control-buffer nil
1152 "*Non-nil means C-h should not invoke Emacs help in control buffer.
1153Instead, C-h jumps to previous difference.")
1154
1155(defvar ediff-temp-file-prefix
1156 (let ((env (or (getenv "TMPDIR")
1157 (getenv "TMP")
1158 (getenv "TEMP")))
1159 d)
1160 (setq d (if (and env (> (length env) 0))
1161 env
4ae69eac
MK
1162 (cond ((memq system-type '(vax-vms axp-vms)) "SYS$SCRATCH:")
1163 ((eq system-type 'ms-dos) "c:/")
1164 (t "/tmp"))))
475f9031
KH
1165 ;; The following is to make sure we get something to which we can
1166 ;; add directory levels on VMS.
1167 (setq d (file-name-as-directory (directory-file-name d)))
475f9031
KH
1168 )
1169 "*Prefix to put on Ediff temporary file names.
1170Do not start with `~/' or `~user-name/'.")
1171
1172(defvar ediff-temp-file-mode 384 ; u=rw only
1173 "*Mode for Ediff temporary files.")
1174
1175;; Metacharacters that have to be protected from the shell when executing
1176;; a diff/diff3 command.
1177(defvar ediff-metachars "[ \t\n!\"#$&'()*;<=>?[\\^`{|~]"
1178 "Characters that must be quoted with \\ when used in a shell command line.
1179More precisely, a regexp to match any one such character.")
1180
4ae69eac
MK
1181;; needed to simulate frame-char-width in XEmacs.
1182(defvar ediff-H-glyph (if ediff-xemacs-p (make-glyph "H")))
1183
475f9031
KH
1184
1185(ediff-defvar-local ediff-temp-file-A nil
1186 "Temporary file used for refining difference regions in buffer A.")
1187(ediff-defvar-local ediff-temp-file-B nil
1188 "Temporary file used for refining difference regions in buffer B.")
1189(ediff-defvar-local ediff-temp-file-C nil
1190 "Temporary file used for refining difference regions in buffer C.")
1191
1192;;; In-line functions
1193
1194(defsubst ediff-file-remote-p (file-name)
1195 (if (fboundp ediff-ange-ftp-ftp-name)
1196 (funcall ediff-ange-ftp-ftp-name file-name)))
1197
475f9031
KH
1198
1199(defsubst ediff-frame-unsplittable-p (frame)
41d25ad0 1200 (cdr (assq 'unsplittable (frame-parameters frame))))
475f9031
KH
1201
1202(defsubst ediff-get-next-window (wind prev-wind)
1203 (or (window-live-p wind)
1204 (setq wind (if prev-wind
1205 (next-window wind)
1206 (selected-window)))))
1207
475f9031
KH
1208
1209(defsubst ediff-kill-buffer-carefully (buf)
1210 "Kill buffer BUF if it exists."
1211 (if (ediff-buffer-live-p buf)
1212 (kill-buffer (get-buffer buf))))
1213
1214
1215(defsubst ediff-highlight-diff (n)
1216 "Put face on diff N. Invoked for X displays only."
1217 (ediff-highlight-diff-in-one-buffer n 'A)
1218 (ediff-highlight-diff-in-one-buffer n 'B)
8343426b
MK
1219 (ediff-highlight-diff-in-one-buffer n 'C)
1220 (ediff-highlight-diff-in-one-buffer n 'Ancestor)
1221 )
475f9031
KH
1222
1223
1224(defsubst ediff-unhighlight-diff ()
1225 "Remove overlays from buffers A, B, and C."
1226 (ediff-unhighlight-diff-in-one-buffer 'A)
1227 (ediff-unhighlight-diff-in-one-buffer 'B)
8343426b
MK
1228 (ediff-unhighlight-diff-in-one-buffer 'C)
1229 (ediff-unhighlight-diff-in-one-buffer 'Ancestor)
1230 )
475f9031
KH
1231
1232;; delete highlighting overlays, restore faces to their original form
1233(defsubst ediff-unhighlight-diffs-totally ()
1234 (ediff-unhighlight-diffs-totally-in-one-buffer 'A)
1235 (ediff-unhighlight-diffs-totally-in-one-buffer 'B)
8343426b
MK
1236 (ediff-unhighlight-diffs-totally-in-one-buffer 'C)
1237 (ediff-unhighlight-diffs-totally-in-one-buffer 'Ancestor)
1238 )
1239
1240(defsubst ediff-background-face (buf-type dif-num)
1241 ;; The value of dif-num is always 1- the one that user sees.
1242 ;; This is why even face is used when dif-num is odd.
1243 (intern (format (if (ediff-odd-p dif-num)
1244 "ediff-even-diff-face-%S"
1245 "ediff-odd-diff-face-%S")
1246 buf-type)))
475f9031
KH
1247
1248
1249;; arg is a record for a given diff in a difference vector
1250;; this record is itself a vector
1251(defsubst ediff-clear-fine-diff-vector (diff-record)
1252 (if diff-record
1253 (mapcar 'ediff-delete-overlay
1254 (ediff-get-fine-diff-vector-from-diff-record diff-record))))
1255
1256(defsubst ediff-clear-fine-differences-in-one-buffer (n buf-type)
1257 (ediff-clear-fine-diff-vector (ediff-get-difference n buf-type))
1258 (ediff-set-fine-diff-vector n buf-type nil))
1259
1260(defsubst ediff-clear-fine-differences (n)
1261 (ediff-clear-fine-differences-in-one-buffer n 'A)
1262 (ediff-clear-fine-differences-in-one-buffer n 'B)
1263 (if ediff-3way-job
1264 (ediff-clear-fine-differences-in-one-buffer n 'C)))
1265
1266
1267(defsubst ediff-convert-fine-diffs-to-overlays (diff-list region-num)
1268 (ediff-set-fine-overlays-in-one-buffer 'A diff-list region-num)
1269 (ediff-set-fine-overlays-in-one-buffer 'B diff-list region-num)
1270 (if ediff-3way-job
1271 (ediff-set-fine-overlays-in-one-buffer 'C diff-list region-num)
1272 ))
1273
1274(defsubst ediff-mouse-event-p (event)
1275 (if ediff-xemacs-p
1276 (button-event-p event)
1277 (string-match "mouse" (format "%S" (event-basic-type event)))
1278 ))
8343426b
MK
1279
1280
1281(defsubst ediff-key-press-event-p (event)
1282 (if ediff-xemacs-p
1283 (key-press-event-p event)
1284 (or (char-or-string-p event) (symbolp event))))
1285
1286(defun ediff-event-point (event)
1287 (cond ((ediff-mouse-event-p event)
1288 (if ediff-xemacs-p
1289 (event-point event)
1290 (posn-point (event-start event))))
1291 ((ediff-key-press-event-p event)
1292 (point))
4ae69eac 1293 (t (error))))
8343426b
MK
1294
1295(defun ediff-event-buffer (event)
1296 (cond ((ediff-mouse-event-p event)
1297 (if ediff-xemacs-p
1298 (event-buffer event)
1299 (window-buffer (posn-window (event-start event)))))
1300 ((ediff-key-press-event-p event)
1301 (current-buffer))
4ae69eac 1302 (t (error))))
8343426b 1303
475f9031
KH
1304
1305(defsubst ediff-frame-iconified-p (frame)
41d25ad0 1306 (if (and (ediff-window-display-p) (frame-live-p frame))
475f9031 1307 (if ediff-xemacs-p
41d25ad0 1308 (frame-iconified-p frame)
475f9031
KH
1309 (eq (frame-visible-p frame) 'icon))))
1310
1311(defsubst ediff-window-visible-p (wind)
41d25ad0 1312 ;; under TTY, window-live-p also means window is visible
475f9031 1313 (and (window-live-p wind)
41d25ad0
KH
1314 (or (not (ediff-window-display-p))
1315 (frame-visible-p (window-frame wind)))))
475f9031
KH
1316
1317
1318(defsubst ediff-frame-char-width (frame)
1319 (if ediff-xemacs-p
41d25ad0 1320 (/ (frame-pixel-width frame) (frame-width frame))
475f9031
KH
1321 (frame-char-width frame)))
1322
8343426b
MK
1323(defun ediff-reset-mouse (&optional frame do-not-grab-mouse)
1324 (or frame (setq frame (selected-frame)))
41d25ad0 1325 (if (ediff-window-display-p)
8343426b
MK
1326 (let ((frame-or-wind frame))
1327 (if ediff-xemacs-p
1328 (setq frame-or-wind (frame-selected-window frame)))
1329 (or do-not-grab-mouse
1330 ;; don't set mouse if the user said to never do this
1331 (not ediff-grab-mouse)
1332 ;; Don't grab on quit, if the user doesn't want to.
1333 ;; If ediff-grab-mouse = t, then mouse won't be grabbed for
1334 ;; sessions that are not part of a group (this is done in
1335 ;; ediff-recenter). The condition below affects only terminating
ceb0ea8b 1336 ;; sessions in session groups (in which case mouse is warped into
8343426b
MK
1337 ;; a meta buffer).
1338 (and (eq ediff-grab-mouse 'maybe)
1339 (memq this-command '(ediff-quit ediff-update-diffs)))
1340 (set-mouse-position frame-or-wind 1 0))
1341 )))
1342
1343(defsubst ediff-spy-after-mouse ()
1344 (setq ediff-mouse-pixel-position (mouse-pixel-position)))
1345
4ae69eac
MK
1346;; It is not easy to find out when the user grabs the mouse, since emacs and
1347;; xemacs behave differently when mouse is not in any frame. Also, this is
1348;; sensitive to when the user grabbed mouse. Not used for now.
8343426b
MK
1349(defun ediff-user-grabbed-mouse ()
1350 (if ediff-mouse-pixel-position
1351 (cond ((not (eq (car ediff-mouse-pixel-position)
1352 (car (mouse-pixel-position)))))
1353 ((and (car (cdr ediff-mouse-pixel-position))
1354 (car (cdr (mouse-pixel-position)))
1355 (cdr (cdr ediff-mouse-pixel-position))
1356 (cdr (cdr (mouse-pixel-position))))
1357 (not (and (< (abs (- (car (cdr ediff-mouse-pixel-position))
1358 (car (cdr (mouse-pixel-position)))))
ceb0ea8b 1359 ediff-mouse-pixel-threshold)
8343426b
MK
1360 (< (abs (- (cdr (cdr ediff-mouse-pixel-position))
1361 (cdr (cdr (mouse-pixel-position)))))
ceb0ea8b 1362 ediff-mouse-pixel-threshold))))
8343426b 1363 (t nil))))
41d25ad0 1364
475f9031
KH
1365(defsubst ediff-frame-char-height (frame)
1366 (if ediff-xemacs-p
4ae69eac 1367 (glyph-height ediff-H-glyph (selected-window frame))
475f9031
KH
1368 (frame-char-height frame)))
1369
1370
1371(defsubst ediff-empty-overlay-p (overl)
1372 (= (ediff-overlay-start overl) (ediff-overlay-end overl)))
4ae69eac
MK
1373
1374;; like overlay-buffer in Emacs. In XEmacs, returns nil if the extent is
1375;; dead. Otherwise, works like extent-buffer
1376(defun ediff-overlay-buffer (overl)
1377 (if ediff-emacs-p
1378 (overlay-buffer overl)
bbe6126c 1379 (and (extent-live-p overl) (extent-object overl))))
4ae69eac
MK
1380
1381;; like overlay-get in Emacs. In XEmacs, returns nil if the extent is
1382;; dead. Otherwise, like extent-property
1383(defun ediff-overlay-get (overl property)
1384 (if ediff-emacs-p
1385 (overlay-get overl property)
1386 (and (extent-live-p overl) (extent-property overl property))))
475f9031
KH
1387
1388;; t if diff region is empty.
1389;; In case of buffer C, t also if it is not a 3way
1390;; comparison job (merging jobs return t as well).
1391(defun ediff-empty-diff-region-p (n buf-type)
1392 (if (eq buf-type 'C)
1393 (or (not ediff-3way-comparison-job)
1394 (= (ediff-get-diff-posn 'C 'beg n)
1395 (ediff-get-diff-posn 'C 'end n)))
1396 (= (ediff-get-diff-posn buf-type 'beg n)
1397 (ediff-get-diff-posn buf-type 'end n))))
1398
1399;; Test if diff region is white space only.
1400;; If 2-way job and buf-type = C, then returns t.
1401(defun ediff-whitespace-diff-region-p (n buf-type)
1402 (or (and (eq buf-type 'C) (not ediff-3way-job))
8343426b 1403 (ediff-empty-diff-region-p n buf-type)
475f9031
KH
1404 (let ((beg (ediff-get-diff-posn buf-type 'beg n))
1405 (end (ediff-get-diff-posn buf-type 'end n)))
1406 (ediff-eval-in-buffer (ediff-get-buffer buf-type)
1407 (save-excursion
1408 (goto-char beg)
1409 (skip-chars-forward ediff-whitespace)
1410 (>= (point) end))))))
1411
1412;; temporarily uses DIR to abbreviate file name
1413;; if DIR is nil, use default-directory
4ae69eac 1414(defun ediff-abbreviate-file-name (file &optional dir)
8343426b
MK
1415 (cond ((stringp dir)
1416 (let ((directory-abbrev-alist (list (cons dir ""))))
1417 (abbreviate-file-name file)))
1418 (ediff-emacs-p (abbreviate-file-name file))
1419 (t ; XEmacs requires addl argument
1420 (abbreviate-file-name file t))))
1421
1422;; Takes a directory and returns the parent directory.
1423;; does nothing to `/'. If the ARG is a regular file,
1424;; strip the file AND the last dir.
1425(defun ediff-strip-last-dir (dir)
1426 (if (not (stringp dir)) (setq dir default-directory))
1427 (setq dir (expand-file-name dir))
1428 (or (file-directory-p dir) (setq dir (file-name-directory dir)))
1429 (let* ((pos (1- (length dir)))
1430 (last-char (aref dir pos)))
1431 (if (and (> pos 0) (= last-char ?/))
1432 (setq dir (substring dir 0 pos)))
1433 (ediff-abbreviate-file-name (file-name-directory dir))))
1434
1435(defun ediff-truncate-string-left (str newlen)
1436 ;; leave space for ... on the left
1437 (let ((len (length str))
1438 substr)
1439 (if (<= len newlen)
1440 str
1441 (setq newlen (max 0 (- newlen 3)))
1442 (setq substr (substring str (max 0 (- len 1 newlen))))
1443 (concat "..." substr))))
1444
1445(defun ediff-abbrev-jobname (jobname)
1446 (cond ((eq jobname 'ediff-directories)
1447 "Compare two directories")
1448 ((eq jobname 'ediff-files)
1449 "Compare two files")
1450 ((eq jobname 'ediff-buffers)
1451 "Compare two buffers")
1452 ((eq jobname 'ediff-directories3)
1453 "Compare three directories")
1454 ((eq jobname 'ediff-files3)
1455 "Compare three files")
1456 ((eq jobname 'ediff-buffers3)
1457 "Compare three buffers")
1458 ((eq jobname 'ediff-revision)
1459 "Compare file with a version")
1460 ((eq jobname 'ediff-directory-revisions)
1461 "Compare dir files with versions")
1462 ((eq jobname 'ediff-merge-directory-revisions)
1463 "Merge dir files with versions")
1464 ((eq jobname 'ediff-merge-directory-revisions-with-ancestor)
1465 "Merge dir versions via ancestors")
1466 (t
1467 (let* ((str (substring (symbol-name jobname) 6))
1468 (len (length str))
1469 (pos 0))
1470 (while (< pos len)
1471 (if (= pos 0)
1472 (aset str pos (upcase (aref str pos))))
1473 (if (= (aref str pos) ?-)
1474 (aset str pos ?\ ))
1475 (setq pos (1+ pos)))
1476 str))))
1477
1478
475f9031
KH
1479
1480(defsubst ediff-get-region-contents (n buf-type ctrl-buf &optional start end)
1481 (ediff-eval-in-buffer
1482 (ediff-eval-in-buffer ctrl-buf (ediff-get-buffer buf-type))
1483 (buffer-substring
1484 (or start (ediff-get-diff-posn buf-type 'beg n ctrl-buf))
1485 (or end (ediff-get-diff-posn buf-type 'end n ctrl-buf)))))
1486
1487;; If ediff modified mode line, strip the modification
1488(defsubst ediff-strip-mode-line-format ()
8343426b 1489 (if (member (car mode-line-format) '(" A: " " B: " " C: " " Ancestor: "))
475f9031
KH
1490 (setq mode-line-format (nth 2 mode-line-format))))
1491
1492;; Verify that we have a difference selected.
1493(defsubst ediff-valid-difference-p (&optional n)
1494 (or n (setq n ediff-current-difference))
1495 (and (>= n 0) (< n ediff-number-of-differences)))
1496
1497(defsubst ediff-show-all-diffs (n)
1498 "Don't skip difference regions."
1499 nil)
8343426b
MK
1500
1501(defsubst Xor (a b)
1502 (or (and a (not b)) (and (not a) b)))
009650b3
MK
1503
1504(defsubst ediff-message-if-verbose (string &rest args)
1505 (if ediff-verbose-p
1506 (apply 'message string args)))
4ae69eac 1507
bbe6126c
MK
1508(defun ediff-file-attributes (filename attr-number)
1509 (let ((handler (find-file-name-handler filename 'find-file-noselect)))
1510 (if (and handler (string-match "ange-ftp" (format "%S" handler)))
1511 -1
1512 (nth attr-number (file-attributes filename)))))
1513(defsubst ediff-file-size (filename)
1514 (ediff-file-attributes filename 7))
1515(defsubst ediff-file-modtime (filename)
1516 (ediff-file-attributes filename 5))
1517
1518
1519
1520
475f9031
KH
1521
1522(provide 'ediff-init)
1523
1524
1525;;; ediff-init.el ends here