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