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