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