2002-01-07 Michael Kifer <kifer@cs.stonybrook.edu>
[bpt/emacs.git] / lisp / ediff-init.el
CommitLineData
4960e757 1;;; ediff-init.el --- Macros, variables, and defsubsts used by Ediff
b578f267 2
50a07e18 3;; Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02 Free Software Foundation, Inc.
475f9031 4
50a07e18 5;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
475f9031
KH
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
3afbc435
PJ
24;;; Commentary:
25
b578f267 26;;; Code:
475f9031 27
bbe6126c
MK
28;; Start compiler pacifier
29(defvar ediff-metajob-name)
30(defvar ediff-meta-buffer)
31(defvar pm-color-alist)
32(defvar ediff-grab-mouse)
33(defvar ediff-mouse-pixel-position)
34(defvar ediff-mouse-pixel-threshold)
35(defvar ediff-whitespace)
36(defvar ediff-multiframe)
2eb4bdca 37(defvar ediff-use-toolbar-p)
50a07e18 38(defvar mswindowsx-bitmap-file-path)
ddc90f39
MK
39
40(and noninteractive
41 (eval-when-compile
42 (load "ange-ftp" 'noerror)))
bbe6126c
MK
43;; end pacifier
44
41d25ad0 45;; Is it XEmacs?
8343426b 46(defconst ediff-xemacs-p (string-match "XEmacs" emacs-version))
41d25ad0
KH
47;; Is it Emacs?
48(defconst ediff-emacs-p (not ediff-xemacs-p))
bbe6126c 49
50a07e18
MK
50;; This is used to avoid compilation warnings. When emacs/xemacs forms can
51;; generate compile time warnings, we use this macro.
52;; In this case, the macro will expand into the form that is appropriate to the
53;; compiler at hand.
54;; Suggested by rms.
55(defmacro ediff-cond-compile-for-xemacs-or-emacs (xemacs-form emacs-form)
56 (if (string-match "XEmacs" emacs-version)
57 xemacs-form emacs-form))
58
bbe6126c
MK
59(defvar ediff-force-faces nil
60 "If t, Ediff will think that it is running on a display that supports faces.
61This is provided as a temporary relief for users of face-capable displays
62that Ediff doesn't know about.")
63
41d25ad0
KH
64;; Are we running as a window application or on a TTY?
65(defsubst ediff-device-type ()
50a07e18
MK
66 (ediff-cond-compile-for-xemacs-or-emacs
67 (device-type (selected-device)) ; xemacs form
68 window-system ; emacs form
69 ))
bbe6126c 70
41d25ad0 71;; in XEmacs: device-type is tty on tty and stream in batch.
4ae69eac
MK
72(defun ediff-window-display-p ()
73 (and (ediff-device-type) (not (memq (ediff-device-type) '(tty pc stream)))))
74
75;; test if supports faces
4ae69eac
MK
76(defun ediff-has-face-support-p ()
77 (cond ((ediff-window-display-p))
78 (ediff-force-faces)
d396e521
MK
79 ((ediff-color-display-p))
80 (ediff-emacs-p (memq (ediff-device-type) '(pc)))
4ae69eac 81 (ediff-xemacs-p (memq (ediff-device-type) '(tty pc)))))
bf5d92c5 82
50a07e18 83;; toolbar support for emacs hasn't been implemented in ediff
2eb4bdca 84(defun ediff-has-toolbar-support-p ()
50a07e18
MK
85 (ediff-cond-compile-for-xemacs-or-emacs
86 (and (featurep 'toolbar) (console-on-window-system-p)) ; xemacs form
87 nil ; emacs form
88 ))
2eb4bdca
MK
89
90(defun ediff-use-toolbar-p ()
91 (and (ediff-has-toolbar-support-p) ;Can it do it ?
92 (boundp 'ediff-use-toolbar-p)
93 ediff-use-toolbar-p)) ;Does the user want it ?
94
acce6d21 95;; Defines SYMBOL as an advertised local variable.
bbe6126c
MK
96;; Performs a defvar, then executes `make-variable-buffer-local' on
97;; the variable. Also sets the `permanent-local' property,
98;; so that `kill-all-local-variables' (called by major-mode setting
99;; commands) won't destroy Ediff control variables.
acce6d21 100;;
bbe6126c 101;; Plagiarised from `emerge-defvar-local' for XEmacs.
acce6d21 102(defmacro ediff-defvar-local (var value doc)
086171bf
MK
103 `(progn
104 (defvar ,var ,value ,doc)
105 (make-variable-buffer-local ',var)
106 (put ',var 'permanent-local t)))
acce6d21 107
bbe6126c
MK
108
109
110;; Variables that control each Ediff session---local to the control buffer.
111
112;; Mode variables
113;; The buffer in which the A variant is stored.
114(ediff-defvar-local ediff-buffer-A nil "")
115;; The buffer in which the B variant is stored.
116(ediff-defvar-local ediff-buffer-B nil "")
3af0304a 117;; The buffer in which the C variant is stored or where the merge buffer lives.
bbe6126c
MK
118(ediff-defvar-local ediff-buffer-C nil "")
119;; Ancestor buffer
120(ediff-defvar-local ediff-ancestor-buffer nil "")
ddc90f39 121;; The Ediff control buffer
bbe6126c 122(ediff-defvar-local ediff-control-buffer nil "")
475f9031 123
50a07e18
MK
124(ediff-defvar-local ediff-temp-indirect-buffer nil
125 "If t, the buffer is a temporary indirect buffer.
126It needs to be killed when we quit the session.")
127
e756eb9f
MK
128
129;; Association between buff-type and ediff-buffer-*
130(defconst ediff-buffer-alist
131 '((?A . ediff-buffer-A)
132 (?B . ediff-buffer-B)
133 (?C . ediff-buffer-C)))
134
475f9031
KH
135;;; Macros
136(defmacro ediff-odd-p (arg)
086171bf 137 `(eq (logand ,arg 1) 1))
475f9031
KH
138
139(defmacro ediff-buffer-live-p (buf)
086171bf 140 `(and ,buf (get-buffer ,buf) (buffer-name (get-buffer ,buf))))
475f9031
KH
141
142(defmacro ediff-get-buffer (arg)
086171bf
MK
143 `(cond ((eq ,arg 'A) ediff-buffer-A)
144 ((eq ,arg 'B) ediff-buffer-B)
145 ((eq ,arg 'C) ediff-buffer-C)
146 ((eq ,arg 'Ancestor) ediff-ancestor-buffer)
147 ))
acce6d21 148
475f9031 149(defmacro ediff-get-value-according-to-buffer-type (buf-type list)
086171bf
MK
150 `(cond ((eq ,buf-type 'A) (nth 0 ,list))
151 ((eq ,buf-type 'B) (nth 1 ,list))
152 ((eq ,buf-type 'C) (nth 2 ,list))
153 ))
acce6d21 154
475f9031 155(defmacro ediff-char-to-buftype (arg)
086171bf
MK
156 `(cond ((memq ,arg '(?a ?A)) 'A)
157 ((memq ,arg '(?b ?B)) 'B)
158 ((memq ,arg '(?c ?C)) 'C)
159 ))
e756eb9f 160
985d0dad 161
e756eb9f
MK
162;; A-list is supposed to be of the form (A . symb) (B . symb)...)
163;; where the first part of any association is a buffer type and the second is
3af0304a
MK
164;; an appropriate symbol. Given buffer-type, this function returns the
165;; symbol. This is used to avoid using `intern'
e756eb9f
MK
166(defsubst ediff-get-symbol-from-alist (buf-type alist)
167 (cdr (assoc buf-type alist)))
acce6d21 168
e756eb9f
MK
169(defconst ediff-difference-vector-alist
170 '((A . ediff-difference-vector-A)
171 (B . ediff-difference-vector-B)
172 (C . ediff-difference-vector-C)
173 (Ancestor . ediff-difference-vector-Ancestor)))
174
475f9031 175(defmacro ediff-get-difference (n buf-type)
086171bf
MK
176 `(aref
177 (symbol-value
178 (ediff-get-symbol-from-alist
179 ,buf-type ediff-difference-vector-alist))
180 ,n))
acce6d21 181
ddc90f39 182;; Tell if it has been previously determined that the region has
475f9031
KH
183;; no diffs other than the white space and newlines
184;; The argument, N, is the diff region number used by Ediff to index the
3af0304a 185;; diff vector. It is 1 less than the number seen by the user.
ddc90f39
MK
186;; Returns:
187;; t if the diffs are whitespace in all buffers
188;; 'A (in 3-buf comparison only) if there are only whitespace
189;; diffs in bufs B and C
190;; 'B (in 3-buf comparison only) if there are only whitespace
191;; diffs in bufs A and C
192;; 'C (in 3-buf comparison only) if there are only whitespace
193;; diffs in bufs A and B
475f9031 194;;
3af0304a 195;; A Difference Vector has the form:
475f9031
KH
196;; [diff diff diff ...]
197;; where each diff has the form:
3af0304a 198;; [overlay fine-diff-vector no-fine-diffs-flag state-of-difference]
475f9031 199;; fine-diff-vector is a vector [fine-diff fine-diff fine-diff ...]
3af0304a
MK
200;; no-fine-diffs-flag says if there are fine differences.
201;; state-of-difference is A, B, C, or nil, indicating which buffer is
202;; different from the other two (used only in 3-way jobs).
475f9031 203(defmacro ediff-no-fine-diffs-p (n)
086171bf 204 `(aref (ediff-get-difference ,n 'A) 2))
acce6d21 205
475f9031 206(defmacro ediff-get-diff-overlay-from-diff-record (diff-rec)
086171bf 207 `(aref ,diff-rec 0))
acce6d21
TTN
208
209(defmacro ediff-get-diff-overlay (n buf-type)
086171bf
MK
210 `(ediff-get-diff-overlay-from-diff-record
211 (ediff-get-difference ,n ,buf-type)))
475f9031
KH
212
213(defmacro ediff-get-fine-diff-vector-from-diff-record (diff-rec)
086171bf 214 `(aref ,diff-rec 1))
acce6d21 215
475f9031 216(defmacro ediff-set-fine-diff-vector (n buf-type fine-vec)
086171bf 217 `(aset (ediff-get-difference ,n ,buf-type) 1 ,fine-vec))
acce6d21 218
475f9031 219(defmacro ediff-get-state-of-diff (n buf-type)
086171bf
MK
220 `(if (ediff-buffer-live-p ediff-buffer-C)
221 (aref (ediff-get-difference ,n ,buf-type) 3)))
475f9031 222(defmacro ediff-set-state-of-diff (n buf-type val)
086171bf 223 `(aset (ediff-get-difference ,n ,buf-type) 3 ,val))
3af0304a 224
475f9031 225(defmacro ediff-get-state-of-merge (n)
086171bf
MK
226 `(if ediff-state-of-merge
227 (aref (aref ediff-state-of-merge ,n) 0)))
475f9031 228(defmacro ediff-set-state-of-merge (n val)
086171bf
MK
229 `(if ediff-state-of-merge
230 (aset (aref ediff-state-of-merge ,n) 0 ,val)))
475f9031 231
3af0304a 232(defmacro ediff-get-state-of-ancestor (n)
086171bf
MK
233 `(if ediff-state-of-merge
234 (aref (aref ediff-state-of-merge ,n) 1)))
3af0304a 235
acce6d21 236;; if flag is t, puts a mark on diff region saying that
3af0304a 237;; the differences are in white space only. If flag is nil,
475f9031
KH
238;; the region is marked as essential (i.e., differences are
239;; not just in the white space and newlines.)
240(defmacro ediff-mark-diff-as-space-only (n flag)
086171bf 241 `(aset (ediff-get-difference ,n 'A) 2 ,flag))
acce6d21 242
475f9031 243(defmacro ediff-get-fine-diff-vector (n buf-type)
086171bf
MK
244 `(ediff-get-fine-diff-vector-from-diff-record
245 (ediff-get-difference ,n ,buf-type)))
acce6d21 246
e756eb9f
MK
247;; Macro to switch to BUFFER, evaluate BODY, returns to original buffer.
248;; Doesn't save the point and mark.
249;; This is `with-current-buffer' with the added test for live buffers."
250(defmacro ediff-with-current-buffer (buffer &rest body)
086171bf 251 `(if (ediff-buffer-live-p ,buffer)
e756eb9f 252 (save-current-buffer
086171bf
MK
253 (set-buffer ,buffer)
254 ,@body)
e756eb9f
MK
255 (or (eq this-command 'ediff-quit)
256 (error ediff-KILLED-VITAL-BUFFER))
086171bf 257 ))
acce6d21 258
475f9031 259
8343426b
MK
260(defsubst ediff-multiframe-setup-p ()
261 (and (ediff-window-display-p) ediff-multiframe))
acce6d21 262
475f9031 263(defmacro ediff-narrow-control-frame-p ()
086171bf
MK
264 `(and (ediff-multiframe-setup-p)
265 (equal ediff-help-message ediff-brief-message-string)))
acce6d21 266
475f9031 267(defmacro ediff-3way-comparison-job ()
086171bf
MK
268 `(memq
269 ediff-job-name
270 '(ediff-files3 ediff-buffers3)))
475f9031 271(ediff-defvar-local ediff-3way-comparison-job nil "")
acce6d21 272
475f9031 273(defmacro ediff-merge-job ()
086171bf
MK
274 `(memq
275 ediff-job-name
276 '(ediff-merge-files
277 ediff-merge-buffers
278 ediff-merge-files-with-ancestor
279 ediff-merge-buffers-with-ancestor
280 ediff-merge-revisions
281 ediff-merge-revisions-with-ancestor)))
475f9031
KH
282(ediff-defvar-local ediff-merge-job nil "")
283
284(defmacro ediff-merge-with-ancestor-job ()
086171bf
MK
285 `(memq
286 ediff-job-name
287 '(ediff-merge-files-with-ancestor
288 ediff-merge-buffers-with-ancestor
289 ediff-merge-revisions-with-ancestor)))
475f9031
KH
290(ediff-defvar-local ediff-merge-with-ancestor-job nil "")
291
292(defmacro ediff-3way-job ()
086171bf 293 `(or ediff-3way-comparison-job ediff-merge-job))
475f9031
KH
294(ediff-defvar-local ediff-3way-job nil "")
295
296;; A diff3 job is like a 3way job, but ediff-merge doesn't require the use
297;; of diff3.
298(defmacro ediff-diff3-job ()
086171bf
MK
299 `(or ediff-3way-comparison-job
300 ediff-merge-with-ancestor-job))
475f9031 301(ediff-defvar-local ediff-diff3-job nil "")
acce6d21 302
41d25ad0 303(defmacro ediff-windows-job ()
086171bf 304 `(memq ediff-job-name '(ediff-windows-wordwise ediff-windows-linewise)))
41d25ad0
KH
305(ediff-defvar-local ediff-windows-job nil "")
306
475f9031 307(defmacro ediff-word-mode-job ()
086171bf 308 `(memq ediff-job-name '(ediff-windows-wordwise ediff-regions-wordwise)))
475f9031
KH
309(ediff-defvar-local ediff-word-mode-job nil "")
310
41d25ad0 311(defmacro ediff-narrow-job ()
086171bf
MK
312 `(memq ediff-job-name '(ediff-windows-wordwise
313 ediff-regions-wordwise
314 ediff-windows-linewise
315 ediff-regions-linewise)))
41d25ad0
KH
316(ediff-defvar-local ediff-narrow-job nil "")
317
8343426b
MK
318;; Note: ediff-merge-directory-revisions-with-ancestor is not treated as an
319;; ancestor metajob, since it behaves differently.
320(defsubst ediff-ancestor-metajob (&optional metajob)
321 (memq (or metajob ediff-metajob-name)
322 '(ediff-merge-directories-with-ancestor
323 ediff-merge-filegroups-with-ancestor)))
324(defsubst ediff-revision-metajob (&optional metajob)
325 (memq (or metajob ediff-metajob-name)
acce6d21 326 '(ediff-directory-revisions
8343426b
MK
327 ediff-merge-directory-revisions
328 ediff-merge-directory-revisions-with-ancestor)))
bbe6126c
MK
329(defsubst ediff-patch-metajob (&optional metajob)
330 (memq (or metajob ediff-metajob-name)
331 '(ediff-multifile-patch)))
332;; metajob involving only one group of files, such as multipatch or directory
333;; revision
334(defsubst ediff-one-filegroup-metajob (&optional metajob)
8343426b 335 (or (ediff-revision-metajob metajob)
bbe6126c 336 (ediff-patch-metajob metajob)
8343426b
MK
337 ;; add more here
338 ))
339(defsubst ediff-collect-diffs-metajob (&optional metajob)
4ae69eac
MK
340 (memq (or metajob ediff-metajob-name)
341 '(ediff-directories
342 ediff-directory-revisions
343 ediff-merge-directories
344 ediff-merge-directories-with-ancestor
345 ediff-merge-directory-revisions
346 ediff-merge-directory-revisions-with-ancestor
347 ;; add more here
348 )))
92c51e07
MK
349(defsubst ediff-merge-metajob (&optional metajob)
350 (memq (or metajob ediff-metajob-name)
351 '(ediff-merge-directories
352 ediff-merge-directories-with-ancestor
353 ediff-merge-directory-revisions
354 ediff-merge-directory-revisions-with-ancestor
acce6d21 355 ediff-merge-filegroups-with-ancestor
92c51e07
MK
356 ;; add more here
357 )))
4ae69eac 358
8343426b
MK
359(defsubst ediff-metajob3 (&optional metajob)
360 (memq (or metajob ediff-metajob-name)
361 '(ediff-merge-directories-with-ancestor
acce6d21 362 ediff-merge-filegroups-with-ancestor
8343426b
MK
363 ediff-directories3
364 ediff-filegroups3)))
365(defsubst ediff-comparison-metajob3 (&optional metajob)
366 (memq (or metajob ediff-metajob-name)
367 '(ediff-directories3 ediff-filegroups3)))
368
bf5d92c5
MK
369;; with no argument, checks if we are in ediff-control-buffer
370;; with argument, checks if we are in ediff-meta-buffer
371(defun ediff-in-control-buffer-p (&optional meta-buf-p)
372 (and (boundp 'ediff-control-buffer)
373 (eq (if meta-buf-p ediff-meta-buffer ediff-control-buffer)
374 (current-buffer))))
375
376(defsubst ediff-barf-if-not-control-buffer (&optional meta-buf-p)
377 (or (ediff-in-control-buffer-p meta-buf-p)
8343426b
MK
378 (error "%S: This command runs in Ediff Control Buffer only!"
379 this-command)))
380
328b4b70
MK
381(defgroup ediff-highlighting nil
382 "Hilighting of difference regions in Ediff"
383 :prefix "ediff-"
384 :group 'ediff)
385
386(defgroup ediff-merge nil
387 "Merging utilities"
388 :prefix "ediff-"
389 :group 'ediff)
390
391(defgroup ediff-hook nil
acce6d21 392 "Hooks run by Ediff"
328b4b70
MK
393 :prefix "ediff-"
394 :group 'ediff)
395
475f9031
KH
396;; Hook variables
397
657f9cb8
MK
398(defcustom ediff-before-setup-hook nil
399 "*Hooks to run before Ediff begins to set up windows and buffers.
400This hook can be used to save the previous window config, which can be restored
401on ediff-quit or ediff-suspend."
402 :type 'hook
acce6d21 403 :group 'ediff-hook)
1e70790f 404(defcustom ediff-before-setup-windows-hook nil
acce6d21
TTN
405 "*Hooks to run before Ediff sets its window configuration.
406This hook is run every time when Ediff arranges its windows.
657f9cb8
MK
407This happens each time Ediff detects that the windows were messed up by the
408user."
1e70790f 409 :type 'hook
acce6d21 410 :group 'ediff-hook)
1e70790f 411(defcustom ediff-after-setup-windows-hook nil
acce6d21 412 "*Hooks to run after Ediff sets its window configuration.
1e70790f
MK
413This can be used to set up control window or icon in a desired place."
414 :type 'hook
328b4b70 415 :group 'ediff-hook)
1e70790f 416(defcustom ediff-before-setup-control-frame-hook nil
475f9031
KH
417 "*Hooks run before setting up the frame to display Ediff Control Panel.
418Can be used to change control frame parameters to position it where it
1e70790f
MK
419is desirable."
420 :type 'hook
328b4b70 421 :group 'ediff-hook)
1e70790f 422(defcustom ediff-after-setup-control-frame-hook nil
475f9031 423 "*Hooks run after setting up the frame to display Ediff Control Panel.
1e70790f
MK
424Can be used to move the frame where it is desired."
425 :type 'hook
328b4b70 426 :group 'ediff-hook)
1e70790f 427(defcustom ediff-startup-hook nil
657f9cb8 428 "*Hooks to run in the control buffer after Ediff has been set up and is ready for the job."
1e70790f 429 :type 'hook
328b4b70 430 :group 'ediff-hook)
1e70790f
MK
431(defcustom ediff-select-hook nil
432 "*Hooks to run after a difference has been selected."
433 :type 'hook
328b4b70 434 :group 'ediff-hook)
1e70790f
MK
435(defcustom ediff-unselect-hook nil
436 "*Hooks to run after a difference has been unselected."
437 :type 'hook
328b4b70 438 :group 'ediff-hook)
1e70790f 439(defcustom ediff-prepare-buffer-hook nil
acce6d21
TTN
440 "*Hooks run after buffers A, B, and C are set up.
441For each buffer, the hooks are run with that buffer made current."
1e70790f 442 :type 'hook
328b4b70 443 :group 'ediff-hook)
1e70790f
MK
444(defcustom ediff-load-hook nil
445 "*Hook run after Ediff is loaded. Can be used to change defaults."
446 :type 'hook
328b4b70 447 :group 'ediff-hook)
acce6d21 448
1e70790f 449(defcustom ediff-mode-hook nil
acce6d21 450 "*Hook run just after ediff-mode is set up in the control buffer.
3af0304a 451This is done before any windows or frames are created. One can use it to
1e70790f
MK
452set local variables that determine how the display looks like."
453 :type 'hook
328b4b70 454 :group 'ediff-hook)
1e70790f
MK
455(defcustom ediff-keymap-setup-hook nil
456 "*Hook run just after the default bindings in Ediff keymap are set up."
457 :type 'hook
328b4b70 458 :group 'ediff-hook)
acce6d21 459
1e70790f
MK
460(defcustom ediff-display-help-hook nil
461 "*Hooks run after preparing the help message."
462 :type 'hook
328b4b70 463 :group 'ediff-hook)
1e70790f 464
7261ece3 465(defcustom ediff-suspend-hook nil
1e70790f
MK
466 "*Hooks to run in the Ediff control buffer when Ediff is suspended."
467 :type 'hook
328b4b70 468 :group 'ediff-hook)
7261ece3 469(defcustom ediff-quit-hook nil
1e70790f
MK
470 "*Hooks to run in the Ediff control buffer after finishing Ediff."
471 :type 'hook
acce6d21 472 :group 'ediff-hook)
1e70790f 473(defcustom ediff-cleanup-hook nil
3af0304a 474 "*Hooks to run on exiting Ediff but before killing the control and variant buffers."
1e70790f 475 :type 'hook
328b4b70 476 :group 'ediff-hook)
475f9031 477
4ae69eac
MK
478;; Error messages
479(defconst ediff-KILLED-VITAL-BUFFER
480 "You have killed a vital Ediff buffer---you must leave Ediff now!")
481(defconst ediff-NO-DIFFERENCES
bbe6126c
MK
482 "Sorry, comparison of identical variants is not what I am made for...")
483(defconst ediff-BAD-DIFF-NUMBER
484 ;; %S stands for this-command, %d - diff number, %d - max diff
3af0304a 485 "%S: Bad diff region number, %d. Valid numbers are 1 to %d")
92c51e07
MK
486(defconst ediff-BAD-INFO (format "
487*** The Info file for Ediff, a part of the standard distribution
488*** of %sEmacs, does not seem to be properly installed.
acce6d21 489***
92c51e07
MK
490*** Please contact your system administrator. "
491 (if ediff-xemacs-p "X" "")))
acce6d21 492
475f9031
KH
493;; Selective browsing
494
495(ediff-defvar-local ediff-skip-diff-region-function 'ediff-show-all-diffs
496 "Function that determines the next/previous diff region to show.
497Should return t for regions to be ignored and nil otherwise.
3af0304a
MK
498This function gets a region number as an argument. The region number
499is the one used internally by Ediff. It is 1 less than the number seen
475f9031
KH
500by the user.")
501
8343426b 502(ediff-defvar-local ediff-hide-regexp-matches-function
acce6d21 503 'ediff-hide-regexp-matches
8343426b
MK
504 "Function to use in determining which regions to hide.
505See the documentation string of `ediff-hide-regexp-matches' for details.")
506(ediff-defvar-local ediff-focus-on-regexp-matches-function
507 'ediff-focus-on-regexp-matches
508 "Function to use in determining which regions to focus on.
509See the documentation string of `ediff-focus-on-regexp-matches' for details.")
510
475f9031
KH
511;; Regexp that determines buf A regions to focus on when skipping to diff
512(ediff-defvar-local ediff-regexp-focus-A "" "")
513;; Regexp that determines buf B regions to focus on when skipping to diff
514(ediff-defvar-local ediff-regexp-focus-B "" "")
515;; Regexp that determines buf C regions to focus on when skipping to diff
516(ediff-defvar-local ediff-regexp-focus-C "" "")
517;; connective that determines whether to focus regions that match both or
518;; one of the regexps
519(ediff-defvar-local ediff-focus-regexp-connective 'and "")
acce6d21 520
475f9031
KH
521;; Regexp that determines buf A regions to ignore when skipping to diff
522(ediff-defvar-local ediff-regexp-hide-A "" "")
523;; Regexp that determines buf B regions to ignore when skipping to diff
524(ediff-defvar-local ediff-regexp-hide-B "" "")
525;; Regexp that determines buf C regions to ignore when skipping to diff
526(ediff-defvar-local ediff-regexp-hide-C "" "")
527;; connective that determines whether to hide regions that match both or
528;; one of the regexps
529(ediff-defvar-local ediff-hide-regexp-connective 'and "")
1e70790f 530
acce6d21
TTN
531
532;;; Copying difference regions between buffers.
533
534;; A list of killed diffs.
1e70790f
MK
535;; A diff is saved here if it is replaced by a diff
536;; from another buffer. This alist has the form:
537;; \((num (buff-object . diff) (buff-object . diff) (buff-object . diff)) ...),
538;; where some buffer-objects may be missing.
539(ediff-defvar-local ediff-killed-diffs-alist nil "")
475f9031 540
4986c2c6
MK
541;; Syntax table to use in ediff-forward-word-function
542;; This is chosen by a heuristic. The important thing is for all buffers to
543;; have the same syntax table. Which is not too important.
544(ediff-defvar-local ediff-syntax-table nil "")
545
475f9031
KH
546
547;; Highlighting
1e70790f
MK
548(defcustom ediff-before-flag-bol (if ediff-xemacs-p (make-glyph "->>") "->>")
549 "*Flag placed before a highlighted block of differences, if block starts at beginning of a line."
550 :type 'string
551 :tag "Region before-flag at beginning of line"
552 :group 'ediff)
553
554(defcustom ediff-after-flag-eol (if ediff-xemacs-p (make-glyph "<<-") "<<-")
555 "*Flag placed after a highlighted block of differences, if block ends at end of a line."
556 :type 'string
557 :tag "Region after-flag at end of line"
558 :group 'ediff)
559
560(defcustom ediff-before-flag-mol (if ediff-xemacs-p (make-glyph "->>") "->>")
561 "*Flag placed before a highlighted block of differences, if block starts in mid-line."
562 :type 'string
563 :tag "Region before-flag in the middle of line"
564 :group 'ediff)
565(defcustom ediff-after-flag-mol (if ediff-xemacs-p (make-glyph "<<-") "<<-")
566 "*Flag placed after a highlighted block of differences, if block ends in mid-line."
567 :type 'string
568 :tag "Region after-flag in the middle of line"
569 :group 'ediff)
475f9031 570
acce6d21
TTN
571
572(ediff-defvar-local ediff-use-faces t "")
573(defcustom ediff-use-faces t
4ae69eac
MK
574 "If t, differences are highlighted using faces, if device supports faces.
575If nil, differences are highlighted using ASCII flags, ediff-before-flag
475f9031 576and ediff-after-flag. On a non-window system, differences are always
2eb4bdca
MK
577highlighted using ASCII flags."
578 :type 'boolean
579 :group 'ediff-highlighting)
475f9031 580
475f9031 581;; this indicates that diff regions are word-size, so fine diffs are
41d25ad0 582;; permanently nixed; used in ediff-windows-wordwise and ediff-regions-wordwise
475f9031 583(ediff-defvar-local ediff-word-mode nil "")
8343426b 584;; Name of the job (ediff-files, ediff-windows, etc.)
475f9031
KH
585(ediff-defvar-local ediff-job-name nil "")
586
587;; Narrowing and ediff-region/windows support
588;; This is a list (overlay-A overlay-B overlay-C)
589;; If set, Ediff compares only those parts of buffers A/B/C that lie within
590;; the bounds of these overlays.
591(ediff-defvar-local ediff-narrow-bounds nil "")
592
593;; List (overlay-A overlay-B overlay-C), where each overlay spans the
594;; entire corresponding buffer.
595(ediff-defvar-local ediff-wide-bounds nil "")
596
597;; Current visibility boundaries in buffers A, B, and C.
3af0304a 598;; This is also a list of overlays. When the user toggles narrow/widen,
475f9031
KH
599;; this list changes from ediff-wide-bounds to ediff-narrow-bounds.
600;; and back.
601(ediff-defvar-local ediff-visible-bounds nil "")
602
603(ediff-defvar-local ediff-start-narrowed t
41d25ad0 604 "Non-nil means start narrowed, if doing ediff-windows-* or ediff-regions-*")
475f9031
KH
605(ediff-defvar-local ediff-quit-widened t
606 "*Non-nil means: when finished, Ediff widens buffers A/B.
607Actually, Ediff restores the scope of visibility that existed at startup.")
1e70790f
MK
608
609(defcustom ediff-keep-variants t
b9fe4732 610 "*nil means prompt to remove unmodified buffers A/B/C at session end.
ceb0ea8b 611Supplying a prefix argument to the quit command `q' temporarily reverses the
1e70790f
MK
612meaning of this variable."
613 :type 'boolean
614 :group 'ediff)
475f9031 615
d84b06ef 616(ediff-defvar-local ediff-highlight-all-diffs t "")
2eb4bdca 617(defcustom ediff-highlight-all-diffs t
475f9031 618 "If nil, only the selected differences are highlighted.
2eb4bdca
MK
619Otherwise, all difference regions are highlighted, but the selected region is
620shown in brighter colors."
621 :type 'boolean
622 :group 'ediff-highlighting)
475f9031
KH
623
624;; A var local to each control panel buffer. Indicates highlighting style
625;; in effect for this buffer: `face', `ascii', nil -- temporarily
626;; unhighlighted, `off' -- turned off \(on a dumb terminal only\).
627(ediff-defvar-local ediff-highlighting-style nil "")
628
acce6d21 629
475f9031
KH
630;; The suffix of the control buffer name.
631(ediff-defvar-local ediff-control-buffer-suffix nil "")
acce6d21 632;; Same as ediff-control-buffer-suffix, but without <,>.
475f9031
KH
633;; It's a number rather than string.
634(ediff-defvar-local ediff-control-buffer-number nil "")
635
636
475f9031 637;; The original values of ediff-protected-variables for buffer A
41d25ad0 638(ediff-defvar-local ediff-buffer-values-orig-A nil "")
475f9031 639;; The original values of ediff-protected-variables for buffer B
41d25ad0 640(ediff-defvar-local ediff-buffer-values-orig-B nil "")
475f9031 641;; The original values of ediff-protected-variables for buffer C
41d25ad0 642(ediff-defvar-local ediff-buffer-values-orig-C nil "")
8343426b
MK
643;; The original values of ediff-protected-variables for buffer Ancestor
644(ediff-defvar-local ediff-buffer-values-orig-Ancestor nil "")
1e70790f 645
e756eb9f
MK
646;; association between buff-type and ediff-buffer-values-orig-*
647(defconst ediff-buffer-values-orig-alist
648 '((A . ediff-buffer-values-orig-A)
649 (B . ediff-buffer-values-orig-B)
650 (C . ediff-buffer-values-orig-C)
651 (Ancestor . ediff-buffer-values-orig-Ancestor)))
652
475f9031 653;; Buffer-local variables to be saved then restored during Ediff sessions
92c51e07 654(defconst ediff-protected-variables '(
acce6d21 655 ;;buffer-read-only
475f9031
KH
656 mode-line-format))
657
475f9031
KH
658;; Vector of differences between the variants. Each difference is
659;; represented by a vector of two overlays plus a vector of fine diffs,
660;; plus a no-fine-diffs flag. The first overlay spans the
661;; difference region in the A buffer and the second overlays the diff in
3af0304a 662;; the B buffer. If a difference section is empty, the corresponding
475f9031
KH
663;; overlay's endpoints coincide.
664;;
3af0304a 665;; The precise form of a Difference Vector for one buffer is:
475f9031
KH
666;; [diff diff diff ...]
667;; where each diff has the form:
3af0304a 668;; [diff-overlay fine-diff-vector no-fine-diffs-flag state-of-diff]
475f9031
KH
669;; fine-diff-vector is a vector [fine-diff-overlay fine-diff-overlay ...]
670;; no-fine-diffs-flag says if there are fine differences.
671;; state-of-difference is A, B, C, or nil, indicating which buffer is
3af0304a 672;; different from the other two (used only in 3-way jobs.
475f9031
KH
673(ediff-defvar-local ediff-difference-vector-A nil "")
674(ediff-defvar-local ediff-difference-vector-B nil "")
675(ediff-defvar-local ediff-difference-vector-C nil "")
8343426b 676(ediff-defvar-local ediff-difference-vector-Ancestor nil "")
e756eb9f
MK
677;; A-list of diff vector types associated with buffer types
678(defconst ediff-difference-vector-alist
679 '((A . ediff-difference-vector-A)
680 (B . ediff-difference-vector-B)
681 (C . ediff-difference-vector-C)
682 (Ancestor . ediff-difference-vector-Ancestor)))
8343426b
MK
683
684;; [ status status status ...]
685;; Each status: [state-of-merge state-of-ancestor]
3af0304a 686;; state-of-merge is default-A, default-B, prefer-A, or prefer-B. It
8343426b
MK
687;; indicates the way a diff region was created in buffer C.
688;; state-of-ancestor says if the corresponding region in ancestor buffer is
689;; empty.
690(ediff-defvar-local ediff-state-of-merge nil "")
475f9031
KH
691
692;; The difference that is currently selected.
693(ediff-defvar-local ediff-current-difference -1 "")
694;; Number of differences found.
695(ediff-defvar-local ediff-number-of-differences nil "")
acce6d21 696
475f9031
KH
697;; Buffer containing the output of diff, which is used by Ediff to step
698;; through files.
699(ediff-defvar-local ediff-diff-buffer nil "")
3af0304a 700;; Like ediff-diff-buffer, but contains context diff. It is not used by
475f9031
KH
701;; Ediff, but it is saved in a file, if user requests so.
702(ediff-defvar-local ediff-custom-diff-buffer nil "")
703;; Buffer used for diff-style fine differences between regions.
704(ediff-defvar-local ediff-fine-diff-buffer nil "")
705;; Temporary buffer used for computing fine differences.
706(defconst ediff-tmp-buffer " *ediff-tmp*" "")
707;; Buffer used for messages
708(defconst ediff-msg-buffer " *ediff-message*" "")
709;; Buffer containing the output of diff when diff returns errors.
710(ediff-defvar-local ediff-error-buffer nil "")
711;; Buffer to display debug info
712(ediff-defvar-local ediff-debug-buffer "*ediff-debug*" "")
713
8343426b
MK
714;; List of ediff control panels associated with each buffer A/B/C/Ancestor.
715;; Not used any more, but may be needed in the future.
716(ediff-defvar-local ediff-this-buffer-ediff-sessions nil "")
475f9031
KH
717
718;; to be deleted in due time
719;; List of difference overlays disturbed by working with the current diff.
720(defvar ediff-disturbed-overlays nil "")
acce6d21 721
475f9031
KH
722;; Priority of non-selected overlays.
723(defvar ediff-shadow-overlay-priority 100 "")
724
1e70790f 725(defcustom ediff-version-control-package 'vc
8343426b 726 "Version control package used.
3af0304a
MK
727Currently, Ediff supports vc.el, rcs.el, pcl-cvs.el, and generic-sc.el. The
728standard Emacs interface to RCS, CVS, SCCS, etc., is vc.el. However, some
729people find the other two packages more convenient. Set this variable to the
1e70790f
MK
730appropriate symbol: `rcs', `pcl-cvs', or `generic-sc' if you so desire."
731 :type 'symbol
732 :group 'ediff)
8343426b 733
4960e757
MK
734(defcustom ediff-coding-system-for-read 'raw-text
735 "*The coding system for read to use when running the diff program as a subprocess.
736In most cases, the default will do. However, under certain circumstances in
737Windows NT/98/95 you might need to use something like 'raw-text-dos here.
738So, if the output that your diff program sends to Emacs contains extra ^M's,
739you might need to experiment here, if the default or 'raw-text-dos doesn't
740work."
741 :type 'symbol
742 :group 'ediff)
743
744(defcustom ediff-coding-system-for-write 'no-conversion
745 "*The coding system for write to use when writing out difference regions
746to temp files when Ediff needs to find fine differences."
747 :type 'symbol
748 :group 'ediff)
749
475f9031 750
50a07e18
MK
751(ediff-cond-compile-for-xemacs-or-emacs
752 (progn ; xemacs
753 (fset 'ediff-read-event (symbol-function 'next-command-event))
754 (fset 'ediff-overlayp (symbol-function 'extentp))
755 (fset 'ediff-make-overlay (symbol-function 'make-extent))
756 (fset 'ediff-delete-overlay (symbol-function 'delete-extent)))
757 (progn ; emacs
758 (fset 'ediff-read-event (symbol-function 'read-event))
759 (fset 'ediff-overlayp (symbol-function 'overlayp))
760 (fset 'ediff-make-overlay (symbol-function 'make-overlay))
761 (fset 'ediff-delete-overlay (symbol-function 'delete-overlay)))
762 )
acce6d21 763
41d25ad0
KH
764;; Check the current version against the major and minor version numbers
765;; using op: cur-vers op major.minor If emacs-major-version or
766;; emacs-minor-version are not defined, we assume that the current version
767;; is hopelessly outdated. We assume that emacs-major-version and
768;; emacs-minor-version are defined. Otherwise, for Emacs/XEmacs 19, if the
769;; current minor version is < 10 (xemacs) or < 23 (emacs) the return value
770;; will be nil (when op is =, >, or >=) and t (when op is <, <=), which may be
3af0304a 771;; incorrect. However, this gives correct result in our cases, since we are
41d25ad0
KH
772;; testing for sufficiently high Emacs versions.
773(defun ediff-check-version (op major minor &optional type-of-emacs)
774 (if (and (boundp 'emacs-major-version) (boundp 'emacs-minor-version))
775 (and (cond ((eq type-of-emacs 'xemacs) ediff-xemacs-p)
776 ((eq type-of-emacs 'emacs) ediff-emacs-p)
777 (t t))
778 (cond ((eq op '=) (and (= emacs-minor-version minor)
779 (= emacs-major-version major)))
780 ((memq op '(> >= < <=))
781 (and (or (funcall op emacs-major-version major)
782 (= emacs-major-version major))
783 (if (= emacs-major-version major)
784 (funcall op emacs-minor-version minor)
785 t)))
786 (t
787 (error "%S: Invalid op in ediff-check-version" op))))
788 (cond ((memq op '(= > >=)) nil)
789 ((memq op '(< <=)) t))))
acce6d21
TTN
790
791
d396e521
MK
792(defun ediff-color-display-p ()
793 (condition-case nil
50a07e18
MK
794 (ediff-cond-compile-for-xemacs-or-emacs
795 (eq (device-class (selected-device)) 'color) ; xemacs form
796 (if (fboundp 'display-color-p) ; emacs form
797 (display-color-p)
798 (x-display-color-p))
799 )
800 (error nil)))
8343426b 801
acce6d21 802
4ae69eac 803(if (ediff-has-face-support-p)
50a07e18
MK
804 (ediff-cond-compile-for-xemacs-or-emacs
805 (progn ; xemacs
806 (defalias 'ediff-valid-color-p 'valid-color-name-p)
807 (defalias 'ediff-get-face 'get-face))
808 (progn ; emacs
809 (defalias 'ediff-valid-color-p (if (fboundp 'color-defined-p)
810 'color-defined-p
811 'x-color-defined-p))
812 (defalias 'ediff-get-face 'internal-get-face))
813 ))
4ae69eac
MK
814
815(if (ediff-window-display-p)
50a07e18
MK
816 (ediff-cond-compile-for-xemacs-or-emacs
817 (progn ; xemacs
818 (fset 'ediff-display-pixel-width (symbol-function 'device-pixel-width))
819 (fset 'ediff-display-pixel-height
820 (symbol-function 'device-pixel-height)))
821 (progn ; emacs
822 (fset 'ediff-display-pixel-width
823 (if (fboundp 'display-pixel-width)
824 (symbol-function 'display-pixel-width)
825 (symbol-function 'x-display-pixel-width)))
826 (fset 'ediff-display-pixel-height
827 (if (fboundp 'display-pixel-height)
828 (symbol-function 'display-pixel-height)
829 (symbol-function 'x-display-pixel-height))))
830 ))
acce6d21 831
657f9cb8 832;; A-list of current-diff-overlay symbols associated with buf types
e756eb9f
MK
833(defconst ediff-current-diff-overlay-alist
834 '((A . ediff-current-diff-overlay-A)
835 (B . ediff-current-diff-overlay-B)
836 (C . ediff-current-diff-overlay-C)
837 (Ancestor . ediff-current-diff-overlay-Ancestor)))
acce6d21 838
657f9cb8 839;; A-list of current-diff-face-* symbols associated with buf types
e756eb9f
MK
840(defconst ediff-current-diff-face-alist
841 '((A . ediff-current-diff-face-A)
842 (B . ediff-current-diff-face-B)
843 (C . ediff-current-diff-face-C)
844 (Ancestor . ediff-current-diff-face-Ancestor)))
acce6d21 845
475f9031 846
8343426b
MK
847(defun ediff-set-overlay-face (extent face)
848 (ediff-overlay-put extent 'face face)
849 (ediff-overlay-put extent 'help-echo 'ediff-region-help-echo))
acce6d21 850
475de6f4
DL
851(defun ediff-region-help-echo (extent-or-window &optional overlay point)
852 (unless overlay
853 (setq overlay extent-or-window))
854 (let ((is-current (ediff-overlay-get overlay 'ediff))
855 (face (ediff-overlay-get overlay 'face))
a21f0bd5
DL
856 (diff-num (ediff-overlay-get overlay 'ediff-diff-num))
857 face-help)
8343426b
MK
858
859 ;; This happens only for refinement overlays
475de6f4
DL
860 (if (stringp face)
861 (setq face (intern face)))
8343426b
MK
862 (setq face-help (and face (get face 'ediff-help-echo)))
863
50575ec2 864 (cond ((and is-current diff-num) ; current diff region
bbe6126c 865 (format "Difference region %S -- current" (1+ diff-num)))
475de6f4 866 (face-help) ; refinement of current diff region
50575ec2 867 (diff-num ; non-current
bbe6126c 868 (format "Difference region %S -- non-current" (1+ diff-num)))
50575ec2 869 (t "")) ; none
30729019 870 ))
8343426b 871
36d57fa9 872
92c51e07
MK
873(defun ediff-set-face-pixmap (face pixmap)
874 "Set face pixmap on a monochrome display."
875 (if (and (ediff-window-display-p) (not (ediff-color-display-p)))
876 (condition-case nil
877 (set-face-background-pixmap face pixmap)
878 (error
879 (message "Pixmap not found for %S: %s" (face-name face) pixmap)
880 (sit-for 1)))))
881
4ae69eac
MK
882(defun ediff-hide-face (face)
883 (if (and (ediff-has-face-support-p) ediff-emacs-p)
884 (add-to-list 'facemenu-unlisted-faces face)))
acce6d21 885
475f9031 886
985d0dad
MK
887
888(defface ediff-current-diff-face-A
889 '((((class color)) (:foreground "firebrick" :background "pale green"))
890 (t (:inverse-video t)))
891 "Face for highlighting the selected difference in buffer A."
892 :group 'ediff-highlighting)
3af0304a 893;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 894;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
895(defvar ediff-current-diff-face-A 'ediff-current-diff-face-A
896 "Face for highlighting the selected difference in buffer A.
3af0304a 897DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
898widget to customize the actual face object `ediff-current-diff-face-A'
899this variable represents.")
985d0dad
MK
900(ediff-hide-face 'ediff-current-diff-face-A)
901;; Until custom.el for XEmacs starts supporting :inverse-video we do this.
902;; This means that some user customization may be trashed.
903(if (and ediff-xemacs-p
904 (ediff-has-face-support-p)
acce6d21 905 (not (ediff-color-display-p)))
985d0dad
MK
906 (copy-face 'modeline 'ediff-current-diff-face-A))
907
908
909
985d0dad
MK
910(defface ediff-current-diff-face-B
911 '((((class color)) (:foreground "DarkOrchid" :background "Yellow"))
912 (t (:inverse-video t)))
913 "Face for highlighting the selected difference in buffer B."
914 :group 'ediff-highlighting)
3af0304a 915;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 916;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
917(defvar ediff-current-diff-face-B 'ediff-current-diff-face-B
918 "Face for highlighting the selected difference in buffer B.
3af0304a 919 this variable. Instead, use the customization
8e41a31c
MK
920widget to customize the actual face `ediff-current-diff-face-B'
921this variable represents.")
985d0dad
MK
922(ediff-hide-face 'ediff-current-diff-face-B)
923;; Until custom.el for XEmacs starts supporting :inverse-video we do this.
924;; This means that some user customization may be trashed.
925(if (and ediff-xemacs-p
926 (ediff-has-face-support-p)
acce6d21 927 (not (ediff-color-display-p)))
985d0dad
MK
928 (copy-face 'modeline 'ediff-current-diff-face-B))
929
985d0dad
MK
930
931(defface ediff-current-diff-face-C
932 '((((class color)) (:foreground "Navy" :background "Pink"))
933 (t (:inverse-video t)))
934 "Face for highlighting the selected difference in buffer C."
935 :group 'ediff-highlighting)
3af0304a 936;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 937;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
938(defvar ediff-current-diff-face-C 'ediff-current-diff-face-C
939 "Face for highlighting the selected difference in buffer C.
3af0304a 940DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
941widget to customize the actual face object `ediff-current-diff-face-C'
942this variable represents.")
985d0dad
MK
943(ediff-hide-face 'ediff-current-diff-face-C)
944;; Until custom.el for XEmacs starts supporting :inverse-video we do this.
945;; This means that some user customization may be trashed.
946(if (and ediff-xemacs-p
947 (ediff-has-face-support-p)
acce6d21 948 (not (ediff-color-display-p)))
985d0dad
MK
949 (copy-face 'modeline 'ediff-current-diff-face-C))
950
985d0dad
MK
951
952(defface ediff-current-diff-face-Ancestor
953 '((((class color)) (:foreground "Black" :background "VioletRed"))
954 (t (:inverse-video t)))
955 "Face for highlighting the selected difference in buffer Ancestor."
956 :group 'ediff-highlighting)
3af0304a 957;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 958;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
959(defvar ediff-current-diff-face-Ancestor 'ediff-current-diff-face-Ancestor
960 "Face for highlighting the selected difference in buffer Ancestor.
3af0304a 961DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
962widget to customize the actual face object `ediff-current-diff-face-Ancestor'
963this variable represents.")
985d0dad
MK
964(ediff-hide-face 'ediff-current-diff-face-Ancestor)
965;; Until custom.el for XEmacs starts supporting :inverse-video we do this.
966;; This means that some user customization may be trashed.
967(if (and ediff-xemacs-p
968 (ediff-has-face-support-p)
acce6d21 969 (not (ediff-color-display-p)))
985d0dad
MK
970 (copy-face 'modeline 'ediff-current-diff-face-Ancestor))
971
985d0dad
MK
972
973(defface ediff-fine-diff-face-A
974 '((((class color)) (:foreground "Navy" :background "sky blue"))
975 (t (:underline t :stipple "gray3")))
976 "Face for highlighting the refinement of the selected diff in buffer A."
977 :group 'ediff-highlighting)
3af0304a 978;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 979;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
980(defvar ediff-fine-diff-face-A 'ediff-fine-diff-face-A
981 "Face for highlighting the fine differences in buffer A.
3af0304a 982DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
983widget to customize the actual face object `ediff-fine-diff-face-A'
984this variable represents.")
985d0dad 985(ediff-hide-face 'ediff-fine-diff-face-A)
c004db97 986
985d0dad
MK
987(defface ediff-fine-diff-face-B
988 '((((class color)) (:foreground "Black" :background "cyan"))
989 (t (:underline t :stipple "gray3")))
990 "Face for highlighting the refinement of the selected diff in buffer B."
991 :group 'ediff-highlighting)
3af0304a 992;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 993;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
994(defvar ediff-fine-diff-face-B 'ediff-fine-diff-face-B
995 "Face for highlighting the fine differences in buffer B.
3af0304a 996DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
997widget to customize the actual face object `ediff-fine-diff-face-B'
998this variable represents.")
985d0dad 999(ediff-hide-face 'ediff-fine-diff-face-B)
c004db97 1000
985d0dad
MK
1001(defface ediff-fine-diff-face-C
1002 '((((class color)) (:foreground "Black" :background "Turquoise"))
1003 (t (:underline t :stipple "gray3")))
1004 "Face for highlighting the refinement of the selected diff in buffer C."
1005 :group 'ediff-highlighting)
3af0304a 1006;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1007;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1008(defvar ediff-fine-diff-face-C 'ediff-fine-diff-face-C
1009 "Face for highlighting the fine differences in buffer C.
3af0304a 1010DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1011widget to customize the actual face object `ediff-fine-diff-face-C'
1012this variable represents.")
985d0dad 1013(ediff-hide-face 'ediff-fine-diff-face-C)
c004db97 1014
985d0dad
MK
1015(defface ediff-fine-diff-face-Ancestor
1016 '((((class color)) (:foreground "Black" :background "Green"))
1017 (t (:underline t :stipple "gray3")))
1018 "Face for highlighting the refinement of the selected diff in the ancestor buffer.
1019At present, this face is not used and no fine differences are computed for the
1020ancestor buffer."
1021 :group 'ediff-highlighting)
3af0304a 1022;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1023;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1024(defvar ediff-fine-diff-face-Ancestor 'ediff-fine-diff-face-Ancestor
1025 "Face for highlighting the fine differences in buffer Ancestor.
3af0304a 1026DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1027widget to customize the actual face object `ediff-fine-diff-face-Ancestor'
1028this variable represents.")
985d0dad 1029(ediff-hide-face 'ediff-fine-diff-face-Ancestor)
c004db97 1030
3af0304a
MK
1031;; Some installs don't have stipple or Stipple. So, try them in turn.
1032(defvar stipple-pixmap
086171bf 1033 (cond ((not (ediff-has-face-support-p)) nil)
3af0304a
MK
1034 ((and (boundp 'x-bitmap-file-path)
1035 (locate-library "stipple" t x-bitmap-file-path)) "stipple")
1036 ((and (boundp 'mswindowsx-bitmap-file-path)
1037 (locate-library "stipple" t mswindowsx-bitmap-file-path)) "stipple")
1038 (t "Stipple")))
1039
985d0dad 1040(defface ediff-even-diff-face-A
086171bf
MK
1041 `((((class color)) (:foreground "Black" :background "light grey"))
1042 (t (:italic t :stipple ,stipple-pixmap)))
985d0dad
MK
1043 "Face for highlighting even-numbered non-current differences in buffer A."
1044 :group 'ediff-highlighting)
3af0304a 1045;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1046;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1047(defvar ediff-even-diff-face-A 'ediff-even-diff-face-A
1048 "Face for highlighting even-numbered non-current differences in buffer A.
3af0304a 1049DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1050widget to customize the actual face object `ediff-even-diff-face-A'
1051this variable represents.")
985d0dad 1052(ediff-hide-face 'ediff-even-diff-face-A)
c004db97 1053
985d0dad 1054(defface ediff-even-diff-face-B
086171bf
MK
1055 `((((class color)) (:foreground "White" :background "Grey"))
1056 (t (:italic t :stipple ,stipple-pixmap)))
985d0dad
MK
1057 "Face for highlighting even-numbered non-current differences in buffer B."
1058 :group 'ediff-highlighting)
3af0304a 1059;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1060;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1061(defvar ediff-even-diff-face-B 'ediff-even-diff-face-B
1062 "Face for highlighting even-numbered non-current differences in buffer B.
3af0304a 1063DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1064widget to customize the actual face object `ediff-even-diff-face-B'
1065this variable represents.")
985d0dad 1066(ediff-hide-face 'ediff-even-diff-face-B)
c004db97 1067
985d0dad 1068(defface ediff-even-diff-face-C
086171bf
MK
1069 `((((class color)) (:foreground "Black" :background "light grey"))
1070 (t (:italic t :stipple ,stipple-pixmap)))
985d0dad
MK
1071 "Face for highlighting even-numbered non-current differences in buffer C."
1072 :group 'ediff-highlighting)
3af0304a 1073;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1074;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1075(defvar ediff-even-diff-face-C 'ediff-even-diff-face-C
1076 "Face for highlighting even-numbered non-current differences in buffer C.
3af0304a 1077DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1078widget to customize the actual face object `ediff-even-diff-face-C'
1079this variable represents.")
985d0dad 1080(ediff-hide-face 'ediff-even-diff-face-C)
c004db97 1081
985d0dad 1082(defface ediff-even-diff-face-Ancestor
086171bf
MK
1083 `((((class color)) (:foreground "White" :background "Grey"))
1084 (t (:italic t :stipple ,stipple-pixmap)))
985d0dad
MK
1085 "Face for highlighting even-numbered non-current differences in the ancestor buffer."
1086 :group 'ediff-highlighting)
3af0304a 1087;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1088;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1089(defvar ediff-even-diff-face-Ancestor 'ediff-even-diff-face-Ancestor
1090 "Face for highlighting even-numbered non-current differences in buffer Ancestor.
3af0304a 1091DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1092widget to customize the actual face object `ediff-even-diff-face-Ancestor'
1093this variable represents.")
985d0dad 1094(ediff-hide-face 'ediff-even-diff-face-Ancestor)
c004db97 1095
e756eb9f
MK
1096;; Association between buffer types and even-diff-face symbols
1097(defconst ediff-even-diff-face-alist
1098 '((A . ediff-even-diff-face-A)
1099 (B . ediff-even-diff-face-B)
1100 (C . ediff-even-diff-face-C)
1101 (Ancestor . ediff-even-diff-face-Ancestor)))
1102
985d0dad
MK
1103(defface ediff-odd-diff-face-A
1104 '((((class color)) (:foreground "White" :background "Grey"))
1105 (t (:italic t :stipple "gray1")))
1106 "Face for highlighting odd-numbered non-current differences in buffer A."
1107 :group 'ediff-highlighting)
3af0304a 1108;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1109;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1110(defvar ediff-odd-diff-face-A 'ediff-odd-diff-face-A
1111 "Face for highlighting odd-numbered non-current differences in buffer A.
3af0304a 1112DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1113widget to customize the actual face object `ediff-odd-diff-face-A'
1114this variable represents.")
985d0dad 1115(ediff-hide-face 'ediff-odd-diff-face-A)
c004db97 1116
985d0dad
MK
1117
1118(defface ediff-odd-diff-face-B
1119 '((((class color)) (:foreground "Black" :background "light grey"))
1120 (t (:italic t :stipple "gray1")))
1121 "Face for highlighting odd-numbered non-current differences in buffer B."
1122 :group 'ediff-highlighting)
3af0304a 1123;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1124;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1125(defvar ediff-odd-diff-face-B 'ediff-odd-diff-face-B
1126 "Face for highlighting odd-numbered non-current differences in buffer B.
3af0304a 1127DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1128widget to customize the actual face object `ediff-odd-diff-face-B'
1129this variable represents.")
985d0dad 1130(ediff-hide-face 'ediff-odd-diff-face-B)
c004db97 1131
985d0dad
MK
1132(defface ediff-odd-diff-face-C
1133 '((((class color)) (:foreground "White" :background "Grey"))
1134 (t (:italic t :stipple "gray1")))
1135 "Face for highlighting odd-numbered non-current differences in buffer C."
1136 :group 'ediff-highlighting)
3af0304a 1137;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1138;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1139(defvar ediff-odd-diff-face-C 'ediff-odd-diff-face-C
1140 "Face for highlighting odd-numbered non-current differences in buffer C.
3af0304a 1141DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1142widget to customize the actual face object `ediff-odd-diff-face-C'
1143this variable represents.")
985d0dad 1144(ediff-hide-face 'ediff-odd-diff-face-C)
c004db97 1145
985d0dad
MK
1146(defface ediff-odd-diff-face-Ancestor
1147 '((((class color)) (:foreground "Black" :background "light grey"))
1148 (t (:italic t :stipple "gray1")))
1149 "Face for highlighting odd-numbered non-current differences in the ancestor buffer."
1150 :group 'ediff-highlighting)
3af0304a 1151;; An internal variable. Ediff takes the face from here. When unhighlighting,
985d0dad 1152;; this variable is set to nil, then again to the appropriate face.
8e41a31c
MK
1153(defvar ediff-odd-diff-face-Ancestor 'ediff-odd-diff-face-Ancestor
1154 "Face for highlighting odd-numbered non-current differences in buffer Ancestor.
3af0304a 1155DO NOT CHANGE this variable. Instead, use the customization
8e41a31c
MK
1156widget to customize the actual face object `ediff-odd-diff-face-Ancestor'
1157this variable represents.")
985d0dad 1158(ediff-hide-face 'ediff-odd-diff-face-Ancestor)
c004db97 1159
e756eb9f
MK
1160;; Association between buffer types and odd-diff-face symbols
1161(defconst ediff-odd-diff-face-alist
1162 '((A . ediff-odd-diff-face-A)
1163 (B . ediff-odd-diff-face-B)
1164 (C . ediff-odd-diff-face-C)
1165 (Ancestor . ediff-odd-diff-face-Ancestor)))
acce6d21 1166
e756eb9f
MK
1167;; A-list of fine-diff face symbols associated with buffer types
1168(defconst ediff-fine-diff-face-alist
1169 '((A . ediff-fine-diff-face-A)
1170 (B . ediff-fine-diff-face-B)
1171 (C . ediff-fine-diff-face-C)
1172 (Ancestor . ediff-fine-diff-face-Ancestor)))
1173
8343426b
MK
1174;; Help echo
1175(put 'ediff-fine-diff-face-A 'ediff-help-echo
1176 "A `refinement' of the current difference region")
1177(put 'ediff-fine-diff-face-B 'ediff-help-echo
1178 "A `refinement' of the current difference region")
1179(put 'ediff-fine-diff-face-C 'ediff-help-echo
1180 "A `refinement' of the current difference region")
1181(put 'ediff-fine-diff-face-Ancestor 'ediff-help-echo
1182 "A `refinement' of the current difference region")
1183
7261ece3
MK
1184(add-hook 'ediff-quit-hook 'ediff-cleanup-mess)
1185(add-hook 'ediff-suspend-hook 'ediff-default-suspend-function)
1186
475f9031
KH
1187
1188;;; Overlays
1189
8343426b
MK
1190(ediff-defvar-local ediff-current-diff-overlay-A nil
1191 "Overlay for the current difference region in buffer A.")
1192(ediff-defvar-local ediff-current-diff-overlay-B nil
1193 "Overlay for the current difference region in buffer B.")
1194(ediff-defvar-local ediff-current-diff-overlay-C nil
1195 "Overlay for the current difference region in buffer C.")
1196(ediff-defvar-local ediff-current-diff-overlay-Ancestor nil
1197 "Overlay for the current difference region in the ancestor buffer.")
e756eb9f 1198
4960e757 1199;; Compute priority of a current ediff overlay.
8343426b
MK
1200(defun ediff-highest-priority (start end buffer)
1201 (let ((pos (max 1 (1- start)))
1202 ovr-list)
50a07e18
MK
1203 (ediff-cond-compile-for-xemacs-or-emacs
1204 (1+ ediff-shadow-overlay-priority) ; xemacs form
1205 ;; emacs form
1206 (ediff-with-current-buffer buffer
1207 (while (< pos (min (point-max) (1+ end)))
1208 (setq ovr-list (append (overlays-at pos) ovr-list))
1209 (setq pos (next-overlay-change pos)))
1210 (+ 1 ediff-shadow-overlay-priority
1211 (apply 'max
1212 (cons
1213 1
1214 (mapcar
1215 (lambda (ovr)
1216 (if (and ovr
1217 ;; exclude ediff overlays from priority
1218 ;; calculation, or else priority will keep
1219 ;; increasing
1220 (null (ediff-overlay-get ovr 'ediff))
1221 (null (ediff-overlay-get ovr 'ediff-diff-num)))
1222 ;; use the overlay priority or 0
1223 (or (ediff-overlay-get ovr 'priority) 0)
1224 0))
1225 ovr-list)
1226 )
1227 )))
1228 ) ; ediff-cond-compile-for-xemacs-or-emacs
1229 ))
acce6d21
TTN
1230
1231
475f9031
KH
1232(defvar ediff-toggle-read-only-function nil
1233 "*Specifies the function to be used to toggle read-only.
1234If nil, Ediff tries to deduce the function from the binding of C-x C-q.
1235Normally, this is the `toggle-read-only' function, but, if version
1236control is used, it could be `vc-toggle-read-only' or `rcs-toggle-read-only'.")
1237
1e70790f
MK
1238(defcustom ediff-make-buffers-readonly-at-startup nil
1239 "*Make all variant buffers read-only when Ediff starts up.
1240This property can be toggled interactively."
1241 :type 'boolean
1242 :group 'ediff)
1243
475f9031
KH
1244
1245;;; Misc
1246
475f9031
KH
1247;; if nil, this silences some messages
1248(defconst ediff-verbose-p t)
92c51e07 1249
328b4b70 1250(defcustom ediff-autostore-merges 'group-jobs-only
92c51e07 1251 "*Save the results of merge jobs automatically.
b9fe4732 1252nil means don't save automatically. t means always save. Anything else
92c51e07 1253means save automatically only if the merge job is part of a group of jobs, such
2eb4bdca 1254as `ediff-merge-directory' or `ediff-merge-directory-revisions'."
3af0304a 1255 :type '(choice (const nil) (const t) (const group-jobs-only))
328b4b70
MK
1256 :group 'ediff-merge)
1257(make-variable-buffer-local 'ediff-autostore-merges)
92c51e07 1258
3af0304a 1259;; file where the result of the merge is to be saved. used internally
92c51e07 1260(ediff-defvar-local ediff-merge-store-file nil "")
6de3983f
MK
1261
1262(defcustom ediff-merge-filename-prefix "merge_"
1263 "*Prefix to be attached to saved merge buffers."
1264 :type 'string
1265 :group 'ediff-merge)
acce6d21 1266
1e70790f 1267(defcustom ediff-no-emacs-help-in-control-buffer nil
475f9031 1268 "*Non-nil means C-h should not invoke Emacs help in control buffer.
1e70790f
MK
1269Instead, C-h would jump to previous difference."
1270 :type 'boolean
1271 :group 'ediff)
acce6d21 1272
3af0304a
MK
1273;; This is the same as temporary-file-directory from Emacs 20.3.
1274;; Copied over here because XEmacs doesn't have this variable.
acce6d21
TTN
1275(defcustom ediff-temp-file-prefix
1276 (file-name-as-directory
3af0304a
MK
1277 (cond ((boundp 'temporary-file-directory) temporary-file-directory)
1278 ((fboundp 'temp-directory) (temp-directory))
1279 (t "/tmp/")))
acce6d21 1280;;; (file-name-as-directory
3af0304a
MK
1281;;; (cond ((memq system-type '(ms-dos windows-nt))
1282;;; (or (getenv "TEMP") (getenv "TMPDIR") (getenv "TMP") "c:/temp"))
1283;;; ((memq system-type '(vax-vms axp-vms))
1284;;; (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") "SYS$SCRATCH:"))
1285;;; (t
1286;;; (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") "/tmp"))))
475f9031 1287 "*Prefix to put on Ediff temporary file names.
61d5c492 1288Do not start with `~/' or `~USERNAME/'."
328b4b70
MK
1289 :type 'string
1290 :group 'ediff)
475f9031 1291
328b4b70
MK
1292(defcustom ediff-temp-file-mode 384 ; u=rw only
1293 "*Mode for Ediff temporary files."
1294 :type 'integer
1295 :group 'ediff)
acce6d21 1296
475f9031
KH
1297;; Metacharacters that have to be protected from the shell when executing
1298;; a diff/diff3 command.
328b4b70
MK
1299(defcustom ediff-metachars "[ \t\n!\"#$&'()*;<=>?[\\^`{|~]"
1300 "Regexp that matches characters that must be quoted with `\\' in shell command line.
1301This default should work without changes."
1302 :type 'string
1303 :group 'ediff)
475f9031 1304
4ae69eac
MK
1305;; needed to simulate frame-char-width in XEmacs.
1306(defvar ediff-H-glyph (if ediff-xemacs-p (make-glyph "H")))
1307
acce6d21 1308
1e70790f
MK
1309;; Temporary file used for refining difference regions in buffer A.
1310(ediff-defvar-local ediff-temp-file-A nil "")
1311;; Temporary file used for refining difference regions in buffer B.
1312(ediff-defvar-local ediff-temp-file-B nil "")
1313;; Temporary file used for refining difference regions in buffer C.
1314(ediff-defvar-local ediff-temp-file-C nil "")
1315
475f9031 1316
4960e757
MK
1317;; If file-remote-p is defined (as in XEmacs, use it. Otherwise, check
1318;; if find-file-name-handler is defined for 'file-local-copy
1319(defun ediff-file-remote-p (file-name)
1320 (or (and (fboundp 'file-remote-p) (file-remote-p file-name))
7261ece3 1321 (find-file-name-handler file-name 'file-local-copy)))
4960e757
MK
1322
1323;; File for which we can get attributes, such as size or date
1324(defun ediff-listable-file (file-name)
1325 (let ((handler (find-file-name-handler file-name 'file-local-copy)))
1326 (or (null handler) (eq handler 'dired-handler-fn))))
475f9031 1327
acce6d21 1328
475f9031 1329(defsubst ediff-frame-unsplittable-p (frame)
41d25ad0 1330 (cdr (assq 'unsplittable (frame-parameters frame))))
475f9031
KH
1331
1332(defsubst ediff-get-next-window (wind prev-wind)
1333 (or (window-live-p wind)
1334 (setq wind (if prev-wind
1335 (next-window wind)
1336 (selected-window)))))
1337
475f9031
KH
1338
1339(defsubst ediff-kill-buffer-carefully (buf)
1340 "Kill buffer BUF if it exists."
1341 (if (ediff-buffer-live-p buf)
1342 (kill-buffer (get-buffer buf))))
92c51e07 1343
ddc90f39
MK
1344(defsubst ediff-background-face (buf-type dif-num)
1345 ;; The value of dif-num is always 1- the one that user sees.
1346 ;; This is why even face is used when dif-num is odd.
e756eb9f
MK
1347 (ediff-get-symbol-from-alist
1348 buf-type (if (ediff-odd-p dif-num)
1349 ediff-even-diff-face-alist
1350 ediff-odd-diff-face-alist)
1351 ))
ddc90f39 1352
92c51e07
MK
1353
1354;; activate faces on diff regions in buffer
1355(defun ediff-paint-background-regions-in-one-buffer (buf-type unhighlight)
acce6d21 1356 (let ((diff-vector
e756eb9f
MK
1357 (eval (ediff-get-symbol-from-alist
1358 buf-type ediff-difference-vector-alist)))
92c51e07 1359 overl diff-num)
3af0304a
MK
1360 (mapcar (lambda (rec)
1361 (setq overl (ediff-get-diff-overlay-from-diff-record rec)
1362 diff-num (ediff-overlay-get overl 'ediff-diff-num))
1363 (if (ediff-overlay-buffer overl)
1364 ;; only if overlay is alive
1365 (ediff-set-overlay-face
1366 overl
1367 (if (not unhighlight)
1368 (ediff-background-face buf-type diff-num))))
1369 )
92c51e07
MK
1370 diff-vector)))
1371
1372
1373;; activate faces on diff regions in all buffers
1374(defun ediff-paint-background-regions (&optional unhighlight)
1375 (ediff-paint-background-regions-in-one-buffer
1376 'A unhighlight)
1377 (ediff-paint-background-regions-in-one-buffer
1378 'B unhighlight)
1379 (ediff-paint-background-regions-in-one-buffer
1380 'C unhighlight)
1381 (ediff-paint-background-regions-in-one-buffer
1382 'Ancestor unhighlight))
1383
acce6d21 1384
475f9031
KH
1385;; arg is a record for a given diff in a difference vector
1386;; this record is itself a vector
1387(defsubst ediff-clear-fine-diff-vector (diff-record)
1388 (if diff-record
1389 (mapcar 'ediff-delete-overlay
1390 (ediff-get-fine-diff-vector-from-diff-record diff-record))))
acce6d21 1391
475f9031
KH
1392(defsubst ediff-clear-fine-differences-in-one-buffer (n buf-type)
1393 (ediff-clear-fine-diff-vector (ediff-get-difference n buf-type))
1394 (ediff-set-fine-diff-vector n buf-type nil))
acce6d21 1395
475f9031
KH
1396(defsubst ediff-clear-fine-differences (n)
1397 (ediff-clear-fine-differences-in-one-buffer n 'A)
1398 (ediff-clear-fine-differences-in-one-buffer n 'B)
1399 (if ediff-3way-job
1400 (ediff-clear-fine-differences-in-one-buffer n 'C)))
acce6d21 1401
475f9031 1402
475f9031 1403(defsubst ediff-mouse-event-p (event)
50a07e18
MK
1404 (ediff-cond-compile-for-xemacs-or-emacs
1405 (button-event-p event) ; xemacs form
1406 (string-match "mouse" (format "%S" (event-basic-type event))) ; emacs form
1407 ))
8343426b
MK
1408
1409
1410(defsubst ediff-key-press-event-p (event)
50a07e18
MK
1411 (ediff-cond-compile-for-xemacs-or-emacs
1412 (key-press-event-p event) ; xemacs form
1413 (or (char-or-string-p event) (symbolp event)) ; emacs form
1414 ))
8343426b
MK
1415
1416(defun ediff-event-point (event)
1417 (cond ((ediff-mouse-event-p event)
50a07e18
MK
1418 (ediff-cond-compile-for-xemacs-or-emacs
1419 (event-point event) ; xemacs form
1420 (posn-point (event-start event)) ; emacs form
1421 )
1422 )
8343426b
MK
1423 ((ediff-key-press-event-p event)
1424 (point))
50a07e18 1425 (t (error nil))))
8343426b
MK
1426
1427(defun ediff-event-buffer (event)
1428 (cond ((ediff-mouse-event-p event)
50a07e18
MK
1429 (ediff-cond-compile-for-xemacs-or-emacs
1430 (event-buffer event) ; xemacs form
1431 (window-buffer (posn-window (event-start event))) ; emacs form
1432 )
1433 )
8343426b
MK
1434 ((ediff-key-press-event-p event)
1435 (current-buffer))
50a07e18
MK
1436 (t (error nil))))
1437
1438(defun ediff-event-key (event-or-key)
1439 (ediff-cond-compile-for-xemacs-or-emacs
1440 (if (eventp event-or-key) (event-key event-or-key) event-or-key) ; xemacs
1441 event-or-key ; emacs form
1442 ))
acce6d21
TTN
1443
1444
475f9031 1445(defsubst ediff-frame-iconified-p (frame)
41d25ad0 1446 (if (and (ediff-window-display-p) (frame-live-p frame))
50a07e18
MK
1447 (ediff-cond-compile-for-xemacs-or-emacs
1448 (frame-iconified-p frame) ; xemacs form
1449 (eq (frame-visible-p frame) 'icon) ; emacs form
1450 )
1451 ))
acce6d21 1452
475f9031 1453(defsubst ediff-window-visible-p (wind)
41d25ad0 1454 ;; under TTY, window-live-p also means window is visible
475f9031 1455 (and (window-live-p wind)
41d25ad0
KH
1456 (or (not (ediff-window-display-p))
1457 (frame-visible-p (window-frame wind)))))
acce6d21 1458
475f9031
KH
1459
1460(defsubst ediff-frame-char-width (frame)
50a07e18
MK
1461 (ediff-cond-compile-for-xemacs-or-emacs
1462 (/ (frame-pixel-width frame) (frame-width frame)) ; xemacs
1463 (frame-char-width frame) ; emacs
1464 ))
acce6d21 1465
8343426b
MK
1466(defun ediff-reset-mouse (&optional frame do-not-grab-mouse)
1467 (or frame (setq frame (selected-frame)))
41d25ad0 1468 (if (ediff-window-display-p)
8343426b 1469 (let ((frame-or-wind frame))
acce6d21 1470 (if ediff-xemacs-p
8343426b
MK
1471 (setq frame-or-wind (frame-selected-window frame)))
1472 (or do-not-grab-mouse
1473 ;; don't set mouse if the user said to never do this
acce6d21 1474 (not ediff-grab-mouse)
8343426b
MK
1475 ;; Don't grab on quit, if the user doesn't want to.
1476 ;; If ediff-grab-mouse = t, then mouse won't be grabbed for
1477 ;; sessions that are not part of a group (this is done in
3af0304a 1478 ;; ediff-recenter). The condition below affects only terminating
ceb0ea8b 1479 ;; sessions in session groups (in which case mouse is warped into
8343426b
MK
1480 ;; a meta buffer).
1481 (and (eq ediff-grab-mouse 'maybe)
1482 (memq this-command '(ediff-quit ediff-update-diffs)))
1483 (set-mouse-position frame-or-wind 1 0))
1484 )))
1485
1486(defsubst ediff-spy-after-mouse ()
1487 (setq ediff-mouse-pixel-position (mouse-pixel-position)))
1488
4ae69eac 1489;; It is not easy to find out when the user grabs the mouse, since emacs and
3af0304a 1490;; xemacs behave differently when mouse is not in any frame. Also, this is
4ae69eac 1491;; sensitive to when the user grabbed mouse. Not used for now.
8343426b
MK
1492(defun ediff-user-grabbed-mouse ()
1493 (if ediff-mouse-pixel-position
1494 (cond ((not (eq (car ediff-mouse-pixel-position)
1495 (car (mouse-pixel-position)))))
1496 ((and (car (cdr ediff-mouse-pixel-position))
1497 (car (cdr (mouse-pixel-position)))
1498 (cdr (cdr ediff-mouse-pixel-position))
1499 (cdr (cdr (mouse-pixel-position))))
1500 (not (and (< (abs (- (car (cdr ediff-mouse-pixel-position))
1501 (car (cdr (mouse-pixel-position)))))
ceb0ea8b 1502 ediff-mouse-pixel-threshold)
8343426b
MK
1503 (< (abs (- (cdr (cdr ediff-mouse-pixel-position))
1504 (cdr (cdr (mouse-pixel-position)))))
ceb0ea8b 1505 ediff-mouse-pixel-threshold))))
8343426b 1506 (t nil))))
acce6d21 1507
475f9031 1508(defsubst ediff-frame-char-height (frame)
50a07e18
MK
1509 (ediff-cond-compile-for-xemacs-or-emacs
1510 (glyph-height ediff-H-glyph (selected-window frame)) ; xemacs cse
1511 (frame-char-height frame) ; emacs case
1512 )
1513 )
acce6d21 1514
92c51e07 1515;; Some overlay functions
475f9031 1516
ddc90f39
MK
1517(defsubst ediff-overlay-start (overl)
1518 (if (ediff-overlayp overl)
50a07e18
MK
1519 (ediff-cond-compile-for-xemacs-or-emacs
1520 (extent-start-position overl) ; xemacs form
1521 (overlay-start overl) ; emacs form
1522 )
1523 ))
acce6d21 1524
ddc90f39
MK
1525(defsubst ediff-overlay-end (overl)
1526 (if (ediff-overlayp overl)
50a07e18
MK
1527 (ediff-cond-compile-for-xemacs-or-emacs
1528 (extent-end-position overl) ; xemacs form
1529 (overlay-end overl) ; emacs form
1530 )
1531 ))
ddc90f39 1532
475f9031
KH
1533(defsubst ediff-empty-overlay-p (overl)
1534 (= (ediff-overlay-start overl) (ediff-overlay-end overl)))
4ae69eac 1535
3af0304a
MK
1536;; like overlay-buffer in Emacs. In XEmacs, returns nil if the extent is
1537;; dead. Otherwise, works like extent-buffer
4ae69eac 1538(defun ediff-overlay-buffer (overl)
50a07e18
MK
1539 (ediff-cond-compile-for-xemacs-or-emacs
1540 (and (extent-live-p overl) (extent-object overl)) ; xemacs form
1541 (overlay-buffer overl) ; emacs form
1542 ))
4ae69eac 1543
3af0304a
MK
1544;; like overlay-get in Emacs. In XEmacs, returns nil if the extent is
1545;; dead. Otherwise, like extent-property
4ae69eac 1546(defun ediff-overlay-get (overl property)
50a07e18
MK
1547 (ediff-cond-compile-for-xemacs-or-emacs
1548 (and (extent-live-p overl) (extent-property overl property)) ; xemacs form
1549 (overlay-get overl property) ; emacs form
1550 ))
92c51e07
MK
1551
1552
1553;; These two functions are here because XEmacs refuses to
1554;; handle overlays whose buffers were deleted.
1555(defun ediff-move-overlay (overlay beg end &optional buffer)
1556 "Calls `move-overlay' in Emacs and `set-extent-endpoints' in Lemacs.
1557Checks if overlay's buffer exists before actually doing the move."
1558 (let ((buf (and overlay (ediff-overlay-buffer overlay))))
1559 (if (ediff-buffer-live-p buf)
50a07e18
MK
1560 (ediff-cond-compile-for-xemacs-or-emacs
1561 (set-extent-endpoints overlay beg end) ; xemacs form
1562 (move-overlay overlay beg end buffer) ; emacs form
1563 )
92c51e07
MK
1564 ;; buffer's dead
1565 (if overlay
1566 (ediff-delete-overlay overlay)))))
acce6d21 1567
92c51e07
MK
1568(defun ediff-overlay-put (overlay prop value)
1569 "Calls `overlay-put' or `set-extent-property' depending on Emacs version.
1570Checks if overlay's buffer exists."
1571 (if (ediff-buffer-live-p (ediff-overlay-buffer overlay))
50a07e18
MK
1572 (ediff-cond-compile-for-xemacs-or-emacs
1573 (set-extent-property overlay prop value) ; xemacs form
1574 (overlay-put overlay prop value) ; emacs form
1575 )
92c51e07
MK
1576 (ediff-delete-overlay overlay)))
1577
475f9031
KH
1578;; temporarily uses DIR to abbreviate file name
1579;; if DIR is nil, use default-directory
4ae69eac 1580(defun ediff-abbreviate-file-name (file &optional dir)
8343426b
MK
1581 (cond ((stringp dir)
1582 (let ((directory-abbrev-alist (list (cons dir ""))))
1583 (abbreviate-file-name file)))
50a07e18
MK
1584 (t
1585 (ediff-cond-compile-for-xemacs-or-emacs
1586 ;; XEmacs requires addl argument
1587 (abbreviate-file-name file t) ; xemacs form
1588 (abbreviate-file-name file)) ; emacs form
1589 )
1590 ))
8343426b
MK
1591
1592;; Takes a directory and returns the parent directory.
3af0304a 1593;; does nothing to `/'. If the ARG is a regular file,
8343426b
MK
1594;; strip the file AND the last dir.
1595(defun ediff-strip-last-dir (dir)
1596 (if (not (stringp dir)) (setq dir default-directory))
1597 (setq dir (expand-file-name dir))
1598 (or (file-directory-p dir) (setq dir (file-name-directory dir)))
1599 (let* ((pos (1- (length dir)))
1600 (last-char (aref dir pos)))
1601 (if (and (> pos 0) (= last-char ?/))
1602 (setq dir (substring dir 0 pos)))
1603 (ediff-abbreviate-file-name (file-name-directory dir))))
1604
1605(defun ediff-truncate-string-left (str newlen)
1606 ;; leave space for ... on the left
1607 (let ((len (length str))
1608 substr)
1609 (if (<= len newlen)
1610 str
1611 (setq newlen (max 0 (- newlen 3)))
1612 (setq substr (substring str (max 0 (- len 1 newlen))))
1613 (concat "..." substr))))
1614
3af0304a
MK
1615(defsubst ediff-nonempty-string-p (string)
1616 (and (stringp string) (not (string= string ""))))
1617
2550055a
MK
1618(unless (fboundp 'subst-char-in-string)
1619 (defun subst-char-in-string (fromchar tochar string &optional inplace)
1620 "Replace FROMCHAR with TOCHAR in STRING each time it occurs.
1621Unless optional argument INPLACE is non-nil, return a new string."
1622 (let ((i (length string))
1623 (newstr (if inplace string (copy-sequence string))))
1624 (while (> i 0)
1625 (setq i (1- i))
1626 (if (eq (aref newstr i) fromchar)
1627 (aset newstr i tochar)))
1628 newstr)))
1629
8343426b
MK
1630(defun ediff-abbrev-jobname (jobname)
1631 (cond ((eq jobname 'ediff-directories)
1632 "Compare two directories")
1633 ((eq jobname 'ediff-files)
1634 "Compare two files")
1635 ((eq jobname 'ediff-buffers)
1636 "Compare two buffers")
1637 ((eq jobname 'ediff-directories3)
1638 "Compare three directories")
1639 ((eq jobname 'ediff-files3)
1640 "Compare three files")
1641 ((eq jobname 'ediff-buffers3)
1642 "Compare three buffers")
1643 ((eq jobname 'ediff-revision)
1644 "Compare file with a version")
1645 ((eq jobname 'ediff-directory-revisions)
1646 "Compare dir files with versions")
1647 ((eq jobname 'ediff-merge-directory-revisions)
1648 "Merge dir files with versions")
1649 ((eq jobname 'ediff-merge-directory-revisions-with-ancestor)
1650 "Merge dir versions via ancestors")
1651 (t
7d027816
MK
1652 (capitalize
1653 (subst-char-in-string ?- ?\ (substring (symbol-name jobname) 6))))
1654 ))
acce6d21
TTN
1655
1656
475f9031
KH
1657;; If ediff modified mode line, strip the modification
1658(defsubst ediff-strip-mode-line-format ()
8343426b 1659 (if (member (car mode-line-format) '(" A: " " B: " " C: " " Ancestor: "))
475f9031
KH
1660 (setq mode-line-format (nth 2 mode-line-format))))
1661
1662;; Verify that we have a difference selected.
1663(defsubst ediff-valid-difference-p (&optional n)
1664 (or n (setq n ediff-current-difference))
1665 (and (>= n 0) (< n ediff-number-of-differences)))
acce6d21 1666
475f9031
KH
1667(defsubst ediff-show-all-diffs (n)
1668 "Don't skip difference regions."
1669 nil)
8343426b
MK
1670
1671(defsubst Xor (a b)
1672 (or (and a (not b)) (and (not a) b)))
009650b3
MK
1673
1674(defsubst ediff-message-if-verbose (string &rest args)
1675 (if ediff-verbose-p
1676 (apply 'message string args)))
4ae69eac 1677
bbe6126c 1678(defun ediff-file-attributes (filename attr-number)
4960e757
MK
1679 (if (ediff-listable-file filename)
1680 (nth attr-number (file-attributes filename))
1681 -1)
1682 )
ddc90f39 1683
bbe6126c
MK
1684(defsubst ediff-file-size (filename)
1685 (ediff-file-attributes filename 7))
1686(defsubst ediff-file-modtime (filename)
1687 (ediff-file-attributes filename 5))
1688
1689
92c51e07 1690(defun ediff-convert-standard-filename (fname)
ddc90f39 1691 (if (fboundp 'convert-standard-filename)
92c51e07 1692 (convert-standard-filename fname)
92c51e07 1693 fname))
bbe6126c
MK
1694
1695
4986c2c6
MK
1696(if (fboundp 'with-syntax-table)
1697 (fset 'ediff-with-syntax-table 'with-syntax-table)
1698 ;; stolen from subr.el in emacs 21
1699 (defmacro ediff-with-syntax-table (table &rest body)
1700 (let ((old-table (make-symbol "table"))
1701 (old-buffer (make-symbol "buffer")))
1702 `(let ((,old-table (syntax-table))
1703 (,old-buffer (current-buffer)))
1704 (unwind-protect
1705 (progn
1706 (set-syntax-table (copy-syntax-table ,table))
1707 ,@body)
1708 (save-current-buffer
1709 (set-buffer ,old-buffer)
1710 (set-syntax-table ,old-table)))))))
1711
1712
1713
92c51e07
MK
1714;;; Local Variables:
1715;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun)
e756eb9f
MK
1716;;; eval: (put 'ediff-with-current-buffer 'lisp-indent-hook 1)
1717;;; eval: (put 'ediff-with-current-buffer 'edebug-form-spec '(form body))
92c51e07 1718;;; End:
acce6d21 1719
475f9031
KH
1720(provide 'ediff-init)
1721
3afbc435 1722;;; ediff-init.el ends here