Update FSF's address.
[bpt/emacs.git] / lisp / ediff-wind.el
CommitLineData
475f9031 1;;; ediff-wind.el --- window manipulation utilities
b578f267
EN
2
3;; Copyright (C) 1994, 1995 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
KH
25
26(require 'ediff-init)
27
28
18b5607f
KH
29(defvar ediff-window-setup-function (if (ediff-window-display-p)
30 'ediff-setup-windows-multiframe
31 'ediff-setup-windows-plain)
475f9031
KH
32 "*Function called to set up windows.
33Ediff provides a choice of two functions: ediff-setup-windows-plain, for
34doing everything in one frame, and ediff-setup-windows-multiframe,
35which sets the control panel in a separate frame. Also, if the latter
36function detects that one of the buffers A/B is seen in some other frame,
37it will try to keep that buffer in that frame.
38
39If you don't like the two functions provided---write your own one.
40The basic guidelines:
41 1. It should leave the control buffer current and the control window
42 selected.
43 2. It should set ediff-window-A, ediff-window-B, ediff-window-C,
44 and ediff-control-window to contain window objects that display
45 the corresponding buffers.
46 3. It should accept the following arguments:
47 buffer-A, buffer-B, buffer-C, control-buffer
48 Buffer C may not be used in jobs that compare only two buffers.
49If you plan to do something fancy, take a close look at how the two
50provided functions are written.")
51
52;; indicates if we are in a multiframe setup
53(ediff-defvar-local ediff-multiframe nil "")
54
55;; Share of the frame occupied by the merge window (buffer C)
56(ediff-defvar-local ediff-merge-window-share 0.45 "")
57
58;; The control window.
59(ediff-defvar-local ediff-control-window nil "")
60;; Official window for buffer A
61(ediff-defvar-local ediff-window-A nil "")
62;; Official window for buffer B
63(ediff-defvar-local ediff-window-B nil "")
64;; Official window for buffer C
65(ediff-defvar-local ediff-window-C nil "")
66;; Ediff's window configuration.
67;; Used to minimize the need to rearrange windows.
68(ediff-defvar-local ediff-window-config-saved "" "")
69
70
71(defvar ediff-split-window-function 'split-window-vertically
72 "*The function used to split the main window between buffer-A and buffer-B.
73You can set it to a horizontal split instead of the default vertical split
74by setting this variable to `split-window-horizontally'.
75You can also have your own function to do fancy splits.
76This variable has no effect when buffer-A/B are shown in different frames.
77In this case, Ediff will use those frames to display these buffers.")
78
79(defvar ediff-merge-split-window-function 'split-window-horizontally
80 "*The function used to split the main window between buffer-A and buffer-B.
81You can set it to a vertical split instead of the default horizontal split
82by setting this variable to `split-window-vertically'.
83You can also have your own function to do fancy splits.
84This variable has no effect when buffer-A/B/C are shown in different frames.
85In this case, Ediff will use those frames to display these buffers.")
86
87(defconst ediff-control-frame-parameters
18b5607f 88 (if (ediff-window-display-p)
475f9031
KH
89 (list
90 '(name . "Ediff")
91 ;;'(unsplittable . t)
92 '(minibuffer . nil)
6853a937 93 '(user-position . t) ; Emacs only
18b5607f 94 '(vertical-scroll-bars . nil) ; Emacs only
475f9031 95 '(scrollbar-width . 0) ; XEmacs only
18b5607f 96 '(menu-bar-lines . 0) ; Emacs only
6853a937 97 '(visibility . nil) ; doesn't work for XEmacs yet
475f9031
KH
98 ;; don't lower and auto-raise
99 '(auto-lower . nil)
100 '(auto-raise . t)
101 ;; this blocks queries from window manager as to where to put
102 ;; ediff's control frame. we put the frame outside the display,
103 ;; so the initial frame won't jump all over the screen
18b5607f
KH
104 (cons 'top (if (fboundp 'ediff-display-pixel-height)
105 (1+ (ediff-display-pixel-height))
475f9031 106 3000))
18b5607f
KH
107 (cons 'left (if (fboundp 'ediff-display-pixel-width)
108 (1+ (ediff-display-pixel-width))
475f9031
KH
109 3000))
110 ))
111 "Frame parameters for displaying Ediff Control Panel.
112Do not specify width and height here. These are computed automatically.")
113
6853a937
MK
114;; position of the mouse; used to decide whether to warp the mouse into ctl
115;; frame
116(ediff-defvar-local ediff-mouse-pixel-position nil "")
117
118;; not used for now
50893fe9 119(defvar ediff-mouse-pixel-threshold 30
6853a937
MK
120 "If the user moves mouse more than this many pixels, Ediff won't warp mouse into control window.")
121
122(defvar ediff-grab-mouse t
123 "*If t, Ediff will always grab the mouse and put it in the control frame.
124If 'maybe, Ediff will do it sometimes, but not after operations that require
125relatively long time. If nil, the mouse will be entirely user's
126responsibility.")
127
475f9031
KH
128(defvar ediff-control-frame-position-function 'ediff-make-frame-position
129 "Function to call to determine the desired location for the control panel.
130Expects three parameters: the control buffer, the desired width and height
131of the control frame. It returns an association list
132of the form \(\(top . <position>\) \(left . <position>\)\)")
133
6853a937 134(defvar ediff-control-frame-upward-shift (if ediff-xemacs-p 42 14)
475f9031
KH
135 "*The upward shift of control frame from the top of buffer A's frame.
136Measured in pixels.
137This is used by the default control frame positioning function,
138`ediff-make-frame-position'. This variable is provided for easy
139customization of the default.")
140
141(defvar ediff-narrow-control-frame-leftward-shift (if ediff-xemacs-p 7 3)
142 "*The leftward shift of control frame from the right edge of buf A's frame.
143Measured in characters.
144This is used by the default control frame positioning function,
145`ediff-make-frame-position' to adjust the position of the control frame
146when it shows the short menu. This variable is provided for easy
147customization of the default.")
148
149(defvar ediff-wide-control-frame-rightward-shift 7
150 "*The rightward shift of control frame from the left edge of buf A's frame.
151Measured in characters.
152This is used by the default control frame positioning function,
153`ediff-make-frame-position' to adjust the position of the control frame
154when it shows the full menu. This variable is provided for easy
155customization of the default.")
156
157
158;; Wide frame display
159
160;; t means Ediff is using wide display
161(ediff-defvar-local ediff-wide-display-p nil "")
162;; keeps frame config for toggling wide display
163(ediff-defvar-local ediff-wide-display-orig-parameters nil
164 "Frame parameters to be restored when the user wants to toggle the wide
165display off.")
166(ediff-defvar-local ediff-wide-display-frame nil
167 "Frame to be used for wide display.")
168(ediff-defvar-local ediff-make-wide-display-function 'ediff-make-wide-display
169 "The value is a function that is called to create a wide display.
170The function is called without arguments. It should resize the frame in
171which buffers A, B, and C are to be displayed, and it should save the old
172frame parameters in `ediff-wide-display-orig-parameters'.
173The variable `ediff-wide-display-frame' should be set to contain
174the frame used for the wide display.")
175
176;; Frame used for the control panel in a windowing system.
177(ediff-defvar-local ediff-control-frame nil "")
178
179(defvar ediff-prefer-iconified-control-frame nil
180 "*If t, keep control panel iconified when help message is off.
181This has effect only on a windowing system.
50893fe9 182If t, hitting `?' to toggle control panel off iconifies it.
475f9031
KH
183
184This is only useful in Emacs and only for certain kinds of window managers,
185such as TWM and its derivatives, since the window manager must permit
186keyboard input to go into icons. XEmacs completely ignores keyboard input
187into icons, regardless of the window manager.")
188
189;;; Functions
190
191(defun ediff-get-window-by-clicking (wind prev-wind wind-number)
192 (let (event)
193 (message
194 "Select windows by clicking. Please click on Window %d " wind-number)
195 (while (not (ediff-mouse-event-p (setq event (ediff-read-event))))
196 (if (sit-for 1) ; if sequence of events, wait till the final word
197 (beep 1))
198 (message "Please click on Window %d " wind-number))
199 (ediff-read-event) ; discard event
200 (setq wind (if ediff-xemacs-p
201 (event-window event)
202 (posn-window (event-start event))))
203 ))
204
205
206;; Select the lowest window on the frame.
207(defun ediff-select-lowest-window ()
18b5607f
KH
208 (if ediff-xemacs-p
209 (select-window (frame-lowest-window))
210 (let* ((lowest-window (selected-window))
211 (bottom-edge (car (cdr (cdr (cdr (window-edges))))))
212 (last-window (save-excursion
213 (other-window -1) (selected-window)))
214 (window-search t))
215 (while window-search
216 (let* ((this-window (next-window))
217 (next-bottom-edge
218 (car (cdr (cdr (cdr (window-edges this-window)))))))
219 (if (< bottom-edge next-bottom-edge)
220 (progn
221 (setq bottom-edge next-bottom-edge)
222 (setq lowest-window this-window)))
223
224 (select-window this-window)
225 (if (eq last-window this-window)
226 (progn
227 (select-window lowest-window)
228 (setq window-search nil))))))))
475f9031 229
475f9031
KH
230
231;;; Common window setup routines
232
233;; Set up the window configuration. If POS is given, set the points to
234;; the beginnings of the buffers.
235;; When 3way comparison is added, this will have to choose the appropriate
236;; setup function based on ediff-job-name
237(defun ediff-setup-windows (buffer-A buffer-B buffer-C control-buffer)
238 ;; Make sure we are not in the minibuffer window when we try to delete
239 ;; all other windows.
6853a937 240 (run-hooks 'ediff-before-setup-windows-hook)
475f9031
KH
241 (if (eq (selected-window) (minibuffer-window))
242 (other-window 1))
243
18b5607f
KH
244 ;; in case user did a no-no on a tty
245 (or (ediff-window-display-p)
246 (setq ediff-window-setup-function 'ediff-setup-windows-plain))
247
475f9031
KH
248 (or (ediff-keep-window-config control-buffer)
249 (funcall
250 (ediff-eval-in-buffer control-buffer ediff-window-setup-function)
251 buffer-A buffer-B buffer-C control-buffer))
6853a937 252 (run-hooks 'ediff-after-setup-windows-hook))
475f9031
KH
253
254;; Just set up 3 windows.
255;; Usually used without windowing systems
256;; With windowing, we want to use dedicated frames.
257(defun ediff-setup-windows-plain (buffer-A buffer-B buffer-C control-buffer)
258 (ediff-eval-in-buffer control-buffer
259 (setq ediff-multiframe nil))
260 (if ediff-merge-job
261 (ediff-setup-windows-plain-merge
262 buffer-A buffer-B buffer-C control-buffer)
263 (ediff-setup-windows-plain-compare
264 buffer-A buffer-B buffer-C control-buffer)))
265
266(defun ediff-setup-windows-plain-merge (buf-A buf-B buf-C control-buffer)
18b5607f
KH
267 ;; skip dedicated and unsplittable frames
268 (ediff-destroy-control-frame control-buffer)
269 (let ((window-min-height 2)
475f9031
KH
270 split-window-function
271 merge-window-share merge-window-lines
272 wind-A wind-B wind-C)
273 (ediff-eval-in-buffer control-buffer
274 (setq merge-window-share ediff-merge-window-share
275 ;; this lets us have local versions of ediff-split-window-function
276 split-window-function ediff-split-window-function))
277 (delete-other-windows)
278 (split-window-vertically)
279 (ediff-select-lowest-window)
280 (ediff-setup-control-buffer control-buffer)
281
282 ;; go to the upper window and split it betw A, B, and possibly C
283 (other-window 1)
284 (setq merge-window-lines
285 (max 2 (round (* (window-height) merge-window-share))))
286 (switch-to-buffer buf-A)
287 (setq wind-A (selected-window))
288
6853a937
MK
289 ;; XEmacs used to have a lot of trouble with display
290 ;; It did't set things right unless we tell it to sit still
291 ;; 19.12 seems ok.
292 ;;(if ediff-xemacs-p (sit-for 0))
475f9031
KH
293
294 (split-window-vertically (max 2 (- (window-height) merge-window-lines)))
295 (if (eq (selected-window) wind-A)
296 (other-window 1))
297 (setq wind-C (selected-window))
298 (switch-to-buffer buf-C)
299
300 (select-window wind-A)
301 (funcall split-window-function)
302
303 (if (eq (selected-window) wind-A)
304 (other-window 1))
305 (switch-to-buffer buf-B)
306 (setq wind-B (selected-window))
307
308 (ediff-eval-in-buffer control-buffer
309 (setq ediff-window-A wind-A
310 ediff-window-B wind-B
311 ediff-window-C wind-C))
312
313 (ediff-select-lowest-window)
314 (ediff-setup-control-buffer control-buffer)
315 ))
316
317
318;; This function handles all comparison jobs, including 3way jobs
319(defun ediff-setup-windows-plain-compare (buf-A buf-B buf-C control-buffer)
320 ;; skip dedicated and unsplittable frames
18b5607f
KH
321 (ediff-destroy-control-frame control-buffer)
322 (let ((window-min-height 2)
475f9031
KH
323 split-window-function wind-width-or-height
324 three-way-comparison
18b5607f 325 wind-A-start wind-B-start wind-A wind-B wind-C)
475f9031
KH
326 (ediff-eval-in-buffer control-buffer
327 (setq wind-A-start (ediff-overlay-start
328 (ediff-get-value-according-to-buffer-type
329 'A ediff-narrow-bounds))
330 wind-B-start (ediff-overlay-start
331 (ediff-get-value-according-to-buffer-type
332 'B ediff-narrow-bounds))
475f9031
KH
333 ;; this lets us have local versions of ediff-split-window-function
334 split-window-function ediff-split-window-function
335 three-way-comparison ediff-3way-comparison-job))
336 (delete-other-windows)
337 (split-window-vertically)
338 (ediff-select-lowest-window)
339 (ediff-setup-control-buffer control-buffer)
340
341 ;; go to the upper window and split it betw A, B, and possibly C
342 (other-window 1)
343 (switch-to-buffer buf-A)
344 (setq wind-A (selected-window))
345 (if three-way-comparison
346 (setq wind-width-or-height
347 (/ (if (eq split-window-function 'split-window-vertically)
348 (window-height wind-A)
349 (window-width wind-A))
350 3)))
351
6853a937
MK
352 ;; XEmacs used to have a lot of trouble with display
353 ;; It did't set things right unless we told it to sit still
354 ;; 19.12 seems ok.
355 ;;(if ediff-xemacs-p (sit-for 0))
475f9031
KH
356
357 (funcall split-window-function wind-width-or-height)
358
359 (if (eq (selected-window) wind-A)
360 (other-window 1))
361 (switch-to-buffer buf-B)
362 (setq wind-B (selected-window))
363
364 (if three-way-comparison
365 (progn
366 (funcall split-window-function) ; equally
367 (if (eq (selected-window) wind-B)
368 (other-window 1))
369 (switch-to-buffer buf-C)
370 (setq wind-C (selected-window))))
371
372 (ediff-eval-in-buffer control-buffer
373 (setq ediff-window-A wind-A
374 ediff-window-B wind-B
375 ediff-window-C wind-C))
376
377 ;; It is unlikely that we will want to implement 3way window comparison.
378 ;; So, only buffers A and B are used here.
18b5607f 379 (if ediff-windows-job
475f9031
KH
380 (progn
381 (set-window-start wind-A wind-A-start)
382 (set-window-start wind-B wind-B-start)))
383
384 (ediff-select-lowest-window)
385 (ediff-setup-control-buffer control-buffer)
386 ))
387
388
389;; dispatch the appropriate window setup function
390(defun ediff-setup-windows-multiframe (buf-A buf-B buf-C control-buf)
391 (ediff-eval-in-buffer control-buf
392 (setq ediff-multiframe t))
393 (if ediff-merge-job
394 (ediff-setup-windows-multiframe-merge buf-A buf-B buf-C control-buf)
395 (ediff-setup-windows-multiframe-compare buf-A buf-B buf-C control-buf)))
396
397(defun ediff-setup-windows-multiframe-merge (buf-A buf-B buf-C control-buf)
398;;; Algorithm:
399;;; If A and B are in the same frame but C's frame is different--- use one
400;;; frame for A and B and use a separate frame for C.
401;;; If C's frame is non-existent, then: if the first suitable
402;;; non-dedicated frame is different from A&B's, then use it for C.
403;;; Otherwise, put A,B, and C in one frame.
404;;; If buffers A, B, C are is separate frames, use them to display these
405;;; buffers.
406
18b5607f
KH
407 ;; Skip dedicated or iconified frames.
408 ;; Unsplittable frames are taken care of later.
475f9031
KH
409 (ediff-skip-unsuitable-frames 'ok-unsplittable)
410
18b5607f 411 (let* ((window-min-height 2)
475f9031
KH
412 (wind-A (ediff-get-visible-buffer-window buf-A))
413 (wind-B (ediff-get-visible-buffer-window buf-B))
414 (wind-C (ediff-get-visible-buffer-window buf-C))
18b5607f
KH
415 (frame-A (if wind-A (window-frame wind-A)))
416 (frame-B (if wind-B (window-frame wind-B)))
417 (frame-C (if wind-C (window-frame wind-C)))
475f9031
KH
418 ;; on wide display, do things in one frame
419 (force-one-frame
420 (ediff-eval-in-buffer control-buf ediff-wide-display-p))
421 ;; this lets us have local versions of ediff-split-window-function
422 (split-window-function
423 (ediff-eval-in-buffer control-buf ediff-split-window-function))
424 (orig-wind (selected-window))
18b5607f 425 (orig-frame (selected-frame))
475f9031
KH
426 (use-same-frame (or force-one-frame
427 (eq frame-A (or frame-C orig-frame))
428 (eq frame-B (or frame-C orig-frame))
18b5607f
KH
429 (not (frame-live-p frame-A))
430 (not (frame-live-p frame-B))
431 (and (eq frame-A frame-B)
432 (not (frame-live-p frame-C)))
475f9031
KH
433 ))
434 (use-same-frame-for-AB (and (not use-same-frame)
435 (eq frame-A frame-B)))
436 (merge-window-share (ediff-eval-in-buffer control-buf
437 ediff-merge-window-share))
438 merge-window-lines
439 designated-minibuffer-frame
440 done-A done-B done-C)
441
442 ;; buf-A on its own
443 (if (and (window-live-p wind-A)
444 (null use-same-frame)
445 (null use-same-frame-for-AB))
446 (progn
447 (select-window wind-A)
448 (delete-other-windows)
449 (switch-to-buffer buf-A)
450 (setq wind-A (selected-window))
451 (setq done-A t)))
452
453 ;; buf-B on its own
454 (if (and (window-live-p wind-B) (null use-same-frame)) ; buf B on its own
455 (progn
456 (select-window wind-B)
457 (delete-other-windows)
458 (switch-to-buffer buf-B)
459 (setq wind-B (selected-window))
460 (setq done-B t)))
461
462 ;; buf-C on its own
463 (if (and (window-live-p wind-C) (null use-same-frame)) ; buf C on its own
464 (progn
465 (select-window wind-C)
466 (delete-other-windows)
467 (switch-to-buffer buf-C)
468 (setq wind-C (selected-window))
469 (setq done-C t)))
470
471 (if use-same-frame-for-AB
472 (progn
18b5607f 473 (select-frame frame-A)
475f9031
KH
474 (switch-to-buffer buf-A)
475 (delete-other-windows)
476 (setq wind-A (selected-window))
477
478 (funcall split-window-function)
479 (if (eq (selected-window) wind-A)
480 (other-window 1))
481 (switch-to-buffer buf-B)
482 (setq wind-B (selected-window))
483
484 (setq done-A t
485 done-B t)))
486
487 (if use-same-frame
18b5607f
KH
488 (let ((curr-frame (selected-frame))
489 (window-min-height 2))
475f9031
KH
490 ;; avoid dedicated and non-splittable windows
491 (ediff-skip-unsuitable-frames)
18b5607f 492 (or (eq curr-frame (selected-frame))
475f9031
KH
493 (setq wind-A nil
494 wind-B nil
495 wind-C nil
496 orig-wind (selected-window)))
497
498 ;; set the right frame
499 (cond (wind-A (select-window wind-A))
500 (wind-B (select-window wind-B))
501 (wind-C (select-window wind-C))
502 (t (select-window orig-wind)))
503 (delete-other-windows)
504 (setq merge-window-lines
505 (max 2 (round (* (window-height) merge-window-share))))
506 (switch-to-buffer buf-A)
507 (setq wind-A (selected-window))
508
6853a937
MK
509 ;; XEmacs used to have a lot of trouble with display
510 ;; It did't set things right unless we told it to catch breath
511 ;;(if ediff-xemacs-p (sit-for 0))
475f9031
KH
512
513 (split-window-vertically
514 (max 2 (- (window-height) merge-window-lines)))
515 (if (eq (selected-window) wind-A)
516 (other-window 1))
517 (setq wind-C (selected-window))
518 (switch-to-buffer buf-C)
519
520 (select-window wind-A)
521
522 (funcall split-window-function)
523 (if (eq (selected-window) wind-A)
524 (other-window 1))
525 (switch-to-buffer buf-B)
526 (setq wind-B (selected-window))
527
528 (setq done-A t
529 done-B t
530 done-C t)
531 ))
532
533 (or done-A ; Buf A to be set in its own frame
534 (progn ; It was not set up yet as it wasn't visible
535 (select-window orig-wind)
536 (delete-other-windows)
537 (switch-to-buffer buf-A)
538 (setq wind-A (selected-window))
539 ))
540 (or done-B ; Buf B to be set in its own frame
541 (progn ; It was not set up yet as it wasn't visible
542 (select-window orig-wind)
543 (delete-other-windows)
544 (switch-to-buffer buf-B)
545 (setq wind-B (selected-window))
546 ))
547
548 (or done-C ; Buf C to be set in its own frame.
549 (progn ; It was not set up yet as it wasn't visible
550 (select-window orig-wind)
551 (delete-other-windows)
552 (switch-to-buffer buf-C)
553 (setq wind-C (selected-window))
554 ))
555
556 (ediff-eval-in-buffer control-buf
557 (setq ediff-window-A wind-A
558 ediff-window-B wind-B
559 ediff-window-C wind-C)
18b5607f
KH
560 (setq frame-A (window-frame ediff-window-A)
561 designated-minibuffer-frame
562 (window-frame (minibuffer-window frame-A))))
563
564 (ediff-setup-control-frame control-buf designated-minibuffer-frame)
475f9031
KH
565 ))
566
567
568;; Window setup for all comparison jobs, including 3way comparisons
569(defun ediff-setup-windows-multiframe-compare (buf-A buf-B buf-C control-buf)
570;;; Algorithm:
571;;; If a buffer is seen in a frame, use that frame for that buffer.
572;;; If it is not seen, use the current frame.
573;;; If both buffers are not seen, they share the current frame. If one
574;;; of the buffers is not seen, it is placed in the current frame (where
575;;; ediff started). If that frame is displaying the other buffer, it is
576;;; shared between the two buffers.
577;;; However, if we decide to put both buffers in one frame
578;;; and the selected frame isn't splittable, we create a new frame and
579;;; put both buffers there, event if one of this buffers is visible in
580;;; another frame.
581
582 ;; Skip dedicated or iconified frames.
583 ;; Unsplittable frames are taken care of later.
584 (ediff-skip-unsuitable-frames 'ok-unsplittable)
585
18b5607f 586 (let* ((window-min-height 2)
475f9031
KH
587 (wind-A (ediff-get-visible-buffer-window buf-A))
588 (wind-B (ediff-get-visible-buffer-window buf-B))
589 (wind-C (ediff-get-visible-buffer-window buf-C))
18b5607f
KH
590 (frame-A (if wind-A (window-frame wind-A)))
591 (frame-B (if wind-B (window-frame wind-B)))
592 (frame-C (if wind-C (window-frame wind-C)))
475f9031 593 (ctl-frame-exists-p (ediff-eval-in-buffer control-buf
18b5607f 594 (frame-live-p ediff-control-frame)))
475f9031
KH
595 ;; on wide display, do things in one frame
596 (force-one-frame
597 (ediff-eval-in-buffer control-buf ediff-wide-display-p))
598 ;; this lets us have local versions of ediff-split-window-function
599 (split-window-function
600 (ediff-eval-in-buffer control-buf ediff-split-window-function))
601 (three-way-comparison
602 (ediff-eval-in-buffer control-buf ediff-3way-comparison-job))
603 (orig-wind (selected-window))
604 (use-same-frame (or force-one-frame
605 (eq frame-A frame-B)
606 (if three-way-comparison
607 (or (eq frame-A frame-C)
608 (eq frame-B frame-C)
18b5607f
KH
609 (not (frame-live-p frame-A))
610 (not (frame-live-p frame-B))
611 (not (frame-live-p frame-C))))
612 (and (not (frame-live-p frame-B))
475f9031 613 (or ctl-frame-exists-p
18b5607f
KH
614 (eq frame-A (selected-frame))))
615 (and (not (frame-live-p frame-A))
475f9031 616 (or ctl-frame-exists-p
18b5607f
KH
617 (eq frame-B (selected-frame))))))
618 wind-A-start wind-B-start
475f9031
KH
619 designated-minibuffer-frame
620 done-A done-B done-C)
621
622 (ediff-eval-in-buffer control-buf
623 (setq wind-A-start (ediff-overlay-start
624 (ediff-get-value-according-to-buffer-type
625 'A ediff-narrow-bounds))
626 wind-B-start (ediff-overlay-start
627 (ediff-get-value-according-to-buffer-type
18b5607f 628 'B ediff-narrow-bounds))))
475f9031
KH
629
630 (if (and (window-live-p wind-A) (null use-same-frame)) ; buf-A on its own
631 (progn
632 (select-window wind-A)
633 (delete-other-windows)
634 (switch-to-buffer buf-A)
635 (setq wind-A (selected-window))
636 (setq done-A t)))
637
638 (if (and (window-live-p wind-B) (null use-same-frame)) ; buf B on its own
639 (progn
640 (select-window wind-B)
641 (delete-other-windows)
642 (switch-to-buffer buf-B)
643 (setq wind-B (selected-window))
644 (setq done-B t)))
645
646 (if (and (window-live-p wind-C) (null use-same-frame)) ; buf C on its own
647 (progn
648 (select-window wind-C)
649 (delete-other-windows)
650 (switch-to-buffer buf-C)
651 (setq wind-C (selected-window))
652 (setq done-C t)))
653
654 (if use-same-frame
18b5607f 655 (let ((curr-frame (selected-frame))
475f9031
KH
656 ;; this affects 3way setups only
657 wind-width-or-height)
658 ;; avoid dedicated and non-splittable windows
659 (ediff-skip-unsuitable-frames)
18b5607f 660 (or (eq curr-frame (selected-frame))
475f9031
KH
661 (setq wind-A nil
662 wind-B nil
663 wind-C nil
664 orig-wind (selected-window)))
665
666 ;; set the right frame
667 (cond (wind-A (select-window wind-A))
668 (wind-B (select-window wind-B))
669 (wind-C (select-window wind-C))
670 (t (select-window orig-wind)))
671 (delete-other-windows)
672 (switch-to-buffer buf-A)
673 (setq wind-A (selected-window))
674
6853a937
MK
675 ;; XEmacs used to have a lot of trouble with display
676 ;; It didn't set things right unless we told it to catch breath
677 ;;(if ediff-xemacs-p (sit-for 0))
475f9031
KH
678
679 (if three-way-comparison
680 (setq wind-width-or-height
681 (/
682 (if (eq split-window-function 'split-window-vertically)
683 (window-height wind-A)
684 (window-width wind-A))
685 3)))
686
687 (funcall split-window-function wind-width-or-height)
688 (if (eq (selected-window) wind-A)
689 (other-window 1))
690 (switch-to-buffer buf-B)
691 (setq wind-B (selected-window))
692
693 (if three-way-comparison
694 (progn
695 (funcall split-window-function) ; equally
696 (if (memq (selected-window) (list wind-A wind-B))
697 (other-window 1))
698 (switch-to-buffer buf-C)
699 (setq wind-C (selected-window))))
700 (setq done-A t
701 done-B t
702 done-C t)
703 ))
704
705 (or done-A ; Buf A to be set in its own frame
706 (progn ; It was not set up yet as it wasn't visible
707 (select-window orig-wind)
708 (delete-other-windows)
709 (switch-to-buffer buf-A)
710 (setq wind-A (selected-window))
711 ))
712 (or done-B ; Buf B to be set in its own frame
713 (progn ; It was not set up yet as it wasn't visible
714 (select-window orig-wind)
715 (delete-other-windows)
716 (switch-to-buffer buf-B)
717 (setq wind-B (selected-window))
718 ))
719
720 (if three-way-comparison
721 (or done-C ; Buf C to be set in its own frame
722 (progn ; It was not set up yet as it wasn't visible
723 (select-window orig-wind)
724 (delete-other-windows)
725 (switch-to-buffer buf-C)
726 (setq wind-C (selected-window))
727 )))
728
729 (ediff-eval-in-buffer control-buf
730 (setq ediff-window-A wind-A
731 ediff-window-B wind-B
732 ediff-window-C wind-C)
18b5607f
KH
733
734 (setq frame-A (window-frame ediff-window-A)
735 designated-minibuffer-frame
736 (window-frame (minibuffer-window frame-A))))
475f9031
KH
737
738 ;; It is unlikely that we'll implement ediff-windows that would compare
739 ;; 3 windows at once. So, we don't use buffer C here.
18b5607f 740 (if ediff-windows-job
475f9031
KH
741 (progn
742 (set-window-start wind-A wind-A-start)
743 (set-window-start wind-B wind-B-start)))
744
18b5607f 745 (ediff-setup-control-frame control-buf designated-minibuffer-frame)
475f9031
KH
746 ))
747
748;; skip unsplittable and dedicated windows
749;; create a new splittable frame if none is found
750(defun ediff-skip-unsuitable-frames (&optional ok-unsplittable)
18b5607f 751 (if (ediff-window-display-p)
475f9031
KH
752 (let (last-window)
753 (while (and (not (eq (selected-window) last-window))
754 (or
755 (window-dedicated-p (selected-window))
18b5607f 756 (ediff-frame-iconified-p (selected-frame))
475f9031
KH
757 (if ok-unsplittable
758 nil
18b5607f 759 (ediff-frame-unsplittable-p (selected-frame)))))
475f9031
KH
760 ;; remember where started
761 (or last-window (setq last-window (selected-window)))
762 ;; try new window
763 (other-window 1 t))
764 (if (eq (selected-window) last-window)
765 ;; fed up, no appropriate frame
766 (progn
18b5607f 767 ;;(redraw-display)
f9d5a20f 768 (select-frame (make-frame '((unsplittable)))))))))
475f9031
KH
769
770;; Prepare or refresh control frame
18b5607f
KH
771(defun ediff-setup-control-frame (ctl-buffer designated-minibuffer-frame)
772 (let ((window-min-height 2)
475f9031 773 ctl-frame-iconified-p dont-iconify-ctl-frame deiconify-ctl-frame
6853a937 774 ctl-frame old-ctl-frame lines user-grabbed-mouse
475f9031
KH
775 fheight fwidth adjusted-parameters)
776
777 (ediff-eval-in-buffer ctl-buffer
18b5607f 778 (if ediff-xemacs-p (set-buffer-menubar nil))
6853a937
MK
779 ;;(setq user-grabbed-mouse (ediff-user-grabbed-mouse))
780 (run-hooks 'ediff-before-setup-control-frame-hook))
475f9031
KH
781
782 (setq old-ctl-frame (ediff-eval-in-buffer ctl-buffer ediff-control-frame))
18b5607f
KH
783 ;; Delete the old ctl frame and get a new ctl frame.
784 ;; The old ctl frame is deleted to let emacs reset default minibuffer
785 ;; frame or when the ctl frame needs to be moved.
786 ;; The old frame isn't reused, since ediff-setup-control-frame is called
787 ;; very rarely, so the overhead is minimal.
8485d210 788 (if (frame-live-p old-ctl-frame) (delete-frame old-ctl-frame))
18b5607f
KH
789 ;;(redraw-display)
790 ;; new ctl frame should be created while ctl-buff is current, so that
791 ;; the local default-minibuffer-frame will be consulted and
792 ;; that ediff-control-frame-parameters will have the right value.
8485d210
KH
793 (ediff-eval-in-buffer ctl-buffer
794 (let ((default-minibuffer-frame designated-minibuffer-frame))
18b5607f
KH
795 (setq ctl-frame (make-frame ediff-control-frame-parameters)
796 ediff-control-frame ctl-frame)))
475f9031
KH
797
798 (setq ctl-frame-iconified-p (ediff-frame-iconified-p ctl-frame))
18b5607f 799 (select-frame ctl-frame)
475f9031
KH
800 (if (window-dedicated-p (selected-window))
801 ()
802 (delete-other-windows)
803 (switch-to-buffer ctl-buffer))
804
805 ;; must be before ediff-setup-control-buffer
6853a937
MK
806 ;; just a precaution--we should be in ctl-buffer already
807 (ediff-eval-in-buffer ctl-buffer
808 (make-local-variable 'frame-title-format)
809 (make-local-variable 'frame-icon-title-format) ; XEmacs
810 (make-local-variable 'icon-title-format)) ; Emacs
475f9031
KH
811
812 (ediff-setup-control-buffer ctl-buffer)
813 (setq dont-iconify-ctl-frame
814 (not (string= ediff-help-message ediff-brief-help-message)))
815 (setq deiconify-ctl-frame
816 (and (eq this-command 'ediff-toggle-help)
817 dont-iconify-ctl-frame))
818
819 ;; 1 more line for the modeline
820 (setq lines (if ediff-xemacs-p
821 (+ 2 (count-lines (point-min) (point-max)))
822 (1+ (count-lines (point-min) (point-max))))
823 fheight lines
824 fwidth (+ (ediff-help-message-line-length) 2)
825 adjusted-parameters (append (list
6853a937 826 '(visibility . t)
475f9031
KH
827 (cons 'width fwidth)
828 (cons 'height fheight))
829 (funcall
830 ediff-control-frame-position-function
831 ctl-buffer fwidth fheight)))
6853a937
MK
832 (if ediff-prefer-long-help-message
833 (setq adjusted-parameters
834 (cons '(auto-raise . nil) adjusted-parameters)))
475f9031
KH
835
836 ;; In XEmacs, buffer menubar needs to be killed before frame parameters
6853a937 837 ;; are changed.
18b5607f
KH
838 (if ediff-xemacs-p
839 (progn
840 (set-specifier top-toolbar-height (list ctl-frame 0))
841 (set-specifier bottom-toolbar-height (list ctl-frame 0))
842 (set-specifier left-toolbar-width (list ctl-frame 0))
843 (set-specifier right-toolbar-width (list ctl-frame 0))
6853a937
MK
844 ;; XEmacs needed a redisplay, as it had trouble setting
845 ;; height correctly otherwise.
846 ;;(sit-for 0)
847 ))
475f9031
KH
848
849 ;; Under OS/2 (emx) we have to call modify frame parameters twice, in
850 ;; order to make sure that at least once we do it for non-iconified
851 ;; frame. If appears that in the OS/2 port of Emacs, one can't modify
852 ;; frame parameters of iconified frames.
853 (if (eq system-type 'emx)
18b5607f 854 (modify-frame-parameters ctl-frame adjusted-parameters))
475f9031
KH
855
856 (goto-char (point-min))
857
6853a937 858 (modify-frame-parameters ctl-frame adjusted-parameters)
475f9031
KH
859
860 ;; This works around a bug in 19.25 and earlier. There, if frame gets
861 ;; iconified, the current buffer changes to that of the frame that
862 ;; becomes exposed as a result of this iconification.
863 ;; So, we make sure the current buffer doesn't change.
18b5607f 864 (select-frame ctl-frame)
475f9031
KH
865 (ediff-refresh-control-frame)
866
6853a937
MK
867 (cond ((and ediff-prefer-iconified-control-frame
868 (not ctl-frame-iconified-p) (not dont-iconify-ctl-frame))
869 (iconify-frame ctl-frame))
870 ((or deiconify-ctl-frame (not ctl-frame-iconified-p))
871 (raise-frame ctl-frame)))
475f9031
KH
872
873 (if ediff-xemacs-p
874 (set-window-buffer-dedicated (selected-window) ctl-buffer)
875 (set-window-dedicated-p (selected-window) t))
876
6853a937
MK
877 ;; resynch so the cursor will move to control frame
878 ;; per RMS suggestion
879 (let ((count 7))
880 (sit-for .1)
881 (while (and (not (frame-visible-p ctl-frame)) (> count 0))
882 (setq count (1- count))
883 (sit-for .3)))
884
475f9031 885 (or (ediff-frame-iconified-p ctl-frame)
6853a937
MK
886 ;; don't warp the mouse, unless ediff-grab-mouse = t
887 (ediff-reset-mouse ctl-frame (not (eq ediff-grab-mouse t))))
475f9031
KH
888
889 (if ediff-xemacs-p
890 (ediff-eval-in-buffer ctl-buffer
18b5607f
KH
891 (make-local-variable 'select-frame-hook)
892 (add-hook 'select-frame-hook 'ediff-xemacs-select-frame-hook)
475f9031
KH
893 ))
894
895 (ediff-eval-in-buffer ctl-buffer
6853a937 896 (run-hooks 'ediff-after-setup-control-frame-hook))
18b5607f
KH
897 ))
898
899(defun ediff-destroy-control-frame (ctl-buffer)
900 (ediff-eval-in-buffer ctl-buffer
901 (if (and (ediff-window-display-p) (frame-live-p ediff-control-frame))
902 (let ((ctl-frame ediff-control-frame))
903 (if ediff-xemacs-p
904 (set-buffer-menubar default-menubar))
18b5607f
KH
905 (setq ediff-control-frame nil)
906 (delete-frame ctl-frame)
907 )))
908 (ediff-skip-unsuitable-frames)
6853a937
MK
909 ;;(ediff-reset-mouse nil)
910 )
475f9031
KH
911
912
913;; finds a good place to clip control frame
914(defun ediff-make-frame-position (ctl-buffer ctl-frame-width ctl-frame-height)
915 (ediff-eval-in-buffer ctl-buffer
18b5607f
KH
916 (let* ((frame-A (window-frame ediff-window-A))
917 (frame-A-parameters (frame-parameters frame-A))
6853a937
MK
918 (frame-A-top (eval (cdr (assoc 'top frame-A-parameters))))
919 (frame-A-left (eval (cdr (assoc 'left frame-A-parameters))))
18b5607f 920 (frame-A-width (frame-width frame-A))
475f9031
KH
921 (ctl-frame ediff-control-frame)
922 horizontal-adjustment upward-adjustment
6853a937 923 ctl-frame-top ctl-frame-left)
475f9031
KH
924
925 ;; Multiple control frames are clipped based on the value of
926 ;; ediff-control-buffer-number. This is done in order not to obscure
927 ;; other active control panels.
928 (setq horizontal-adjustment (* 2 ediff-control-buffer-number)
929 upward-adjustment (* -14 ediff-control-buffer-number))
930
6853a937
MK
931 (setq ctl-frame-top
932 (- frame-A-top upward-adjustment ediff-control-frame-upward-shift)
933 ctl-frame-left
934 (+ frame-A-left
935 (if ediff-prefer-long-help-message
936 (* (ediff-frame-char-width ctl-frame)
937 (+ ediff-wide-control-frame-rightward-shift
938 horizontal-adjustment))
939 (- (* frame-A-width (ediff-frame-char-width frame-A))
940 (* (ediff-frame-char-width ctl-frame)
941 (+ ctl-frame-width
942 ediff-narrow-control-frame-leftward-shift
943 horizontal-adjustment))))))
944 ;; keep ctl frame within the visible bounds
945 (setq ctl-frame-top (max ctl-frame-top 1)
946 ctl-frame-left (max ctl-frame-left 1))
947 (setq ctl-frame-top
948 (min ctl-frame-top
949 (- (ediff-display-pixel-height)
950 (* 2 ctl-frame-height
951 (ediff-frame-char-height ctl-frame))))
952 ctl-frame-left
953 (min ctl-frame-left
954 (- (ediff-display-pixel-width)
955 (* ctl-frame-width (ediff-frame-char-width ctl-frame)))))
956
957 (list (cons 'top ctl-frame-top)
958 (cons 'left ctl-frame-left))
959 )))
475f9031 960
18b5607f 961(defun ediff-xemacs-select-frame-hook ()
6853a937
MK
962 (if (and (equal (selected-frame) ediff-control-frame)
963 (not ediff-prefer-long-help-message))
18b5607f 964 (raise-frame ediff-control-frame)))
475f9031
KH
965
966(defun ediff-make-wide-display ()
967 "Construct an alist of parameters for the wide display.
968Saves the old frame parameters in `ediff-wide-display-orig-parameters'.
969The frame to be resized is kept in `ediff-wide-display-frame'.
970This function modifies only the left margin and the width of the display.
971It assumes that it is called from within the control buffer."
18b5607f
KH
972 (if (not (fboundp 'ediff-display-pixel-width))
973 (error "Can't determine display width."))
974 (let* ((frame-A (window-frame ediff-window-A))
975 (frame-A-params (frame-parameters frame-A))
475f9031 976 (cw (ediff-frame-char-width frame-A))
18b5607f 977 (wd (- (/ (ediff-display-pixel-width) cw) 5)))
475f9031 978 (setq ediff-wide-display-orig-parameters
6853a937 979 (list (cons 'left (max 0 (eval (cdr (assoc 'left frame-A-params)))))
475f9031
KH
980 (cons 'width (cdr (assoc 'width frame-A-params))))
981 ediff-wide-display-frame frame-A)
18b5607f 982 (modify-frame-parameters frame-A (list (cons 'left cw)
475f9031
KH
983 (cons 'width wd)))))
984
985
986
987;; Revise the mode line to display which difference we have selected
988;; Also resets modelines of buffers A/B, since they may be clobbered by
989;; anothe invocations of Ediff.
990(defun ediff-refresh-mode-lines ()
991 (let (buf-A-state-diff buf-B-state-diff buf-C-state-diff buf-C-state-merge)
992
993 (if (ediff-valid-difference-p)
994 (setq
995 buf-C-state-diff (ediff-get-state-of-diff ediff-current-difference 'C)
996 buf-C-state-merge (ediff-get-state-of-merge ediff-current-difference)
997 buf-A-state-diff (ediff-get-state-of-diff ediff-current-difference 'A)
998 buf-B-state-diff (ediff-get-state-of-diff ediff-current-difference 'B)
999 buf-A-state-diff (if buf-A-state-diff
1000 (format "[%s] " buf-A-state-diff)
1001 "")
1002 buf-B-state-diff (if buf-B-state-diff
1003 (format "[%s] " buf-B-state-diff)
1004 "")
1005 buf-C-state-diff (if (and (ediff-buffer-live-p ediff-buffer-C)
1006 (or buf-C-state-diff buf-C-state-merge))
6853a937 1007 (format "[%s%s%s] "
475f9031
KH
1008 (or buf-C-state-diff "")
1009 (if buf-C-state-merge
1010 (concat " " buf-C-state-merge)
6853a937
MK
1011 "")
1012 (if (ediff-get-state-of-ancestor
1013 ediff-current-difference)
1014 " AncestorEmpty"
1015 "")
1016 )
475f9031
KH
1017 ""))
1018 (setq buf-A-state-diff ""
1019 buf-B-state-diff ""
1020 buf-C-state-diff ""))
1021
1022 ;; control buffer format
1023 (setq mode-line-format
1024 (list (if (ediff-narrow-control-frame-p) " " "-- ")
1025 mode-line-buffer-identification
1026 " Howdy!"))
1027 ;; control buffer id
1028 (setq mode-line-buffer-identification
1029 (if (ediff-narrow-control-frame-p)
1030 (ediff-make-narrow-control-buffer-id 'skip-name)
1031 (ediff-make-wide-control-buffer-id)))
1032 ;; Force mode-line redisplay
1033 (force-mode-line-update)
1034
18b5607f 1035 (if (and (ediff-window-display-p) (frame-live-p ediff-control-frame))
475f9031
KH
1036 (ediff-refresh-control-frame))
1037
1038 (ediff-eval-in-buffer ediff-buffer-A
1039 (setq ediff-diff-status buf-A-state-diff)
1040 (ediff-strip-mode-line-format)
1041 (setq mode-line-format
1042 (list " A: " 'ediff-diff-status mode-line-format))
1043 (force-mode-line-update))
1044 (ediff-eval-in-buffer ediff-buffer-B
1045 (setq ediff-diff-status buf-B-state-diff)
1046 (ediff-strip-mode-line-format)
1047 (setq mode-line-format
1048 (list " B: " 'ediff-diff-status mode-line-format))
1049 (force-mode-line-update))
1050 (if ediff-3way-job
1051 (ediff-eval-in-buffer ediff-buffer-C
1052 (setq ediff-diff-status buf-C-state-diff)
1053 (ediff-strip-mode-line-format)
1054 (setq mode-line-format
1055 (list " C: " 'ediff-diff-status mode-line-format))
1056 (force-mode-line-update)))
6853a937
MK
1057 (if (ediff-buffer-live-p ediff-ancestor-buffer)
1058 (ediff-eval-in-buffer ediff-ancestor-buffer
1059 (ediff-strip-mode-line-format)
1060 ;; we keep the second dummy string in the mode line format of the
1061 ;; ancestor, since for other buffers Ediff prepends 2 strings and
1062 ;; ediff-strip-mode-line-format expects that.
1063 (setq mode-line-format
1064 (list " Ancestor: "
1065 (cond ((not (stringp buf-C-state-merge))
1066 "")
1067 ((string-match "prefer-A" buf-C-state-merge)
1068 "[=diff(B)] ")
1069 ((string-match "prefer-B" buf-C-state-merge)
1070 "[=diff(A)] ")
1071 (t ""))
1072 mode-line-format))))
475f9031
KH
1073 ))
1074
1075
1076(defun ediff-refresh-control-frame ()
6853a937
MK
1077 (setq frame-title-format (ediff-make-narrow-control-buffer-id)
1078 frame-icon-title-format (ediff-make-narrow-control-buffer-id) ; XEmacs
1079 icon-title-format (ediff-make-narrow-control-buffer-id)) ; Emacs
1080 ;; the emacs part will be modified once the 'name and 'title
1081 ;; frame parameters are separated
1082 (if ediff-emacs-p
1083 (modify-frame-parameters
1084 ediff-control-frame
1085 (list (cons 'name (ediff-make-narrow-control-buffer-id))))
1086 ;; force an update of the frame title
1087 (modify-frame-parameters ediff-control-frame '(()))))
475f9031
KH
1088
1089
1090(defun ediff-make-narrow-control-buffer-id (&optional skip-name)
1091 (concat
1092 (if skip-name
1093 " "
1094 (concat
1095 (cdr (assoc 'name ediff-control-frame-parameters))
1096 ediff-control-buffer-suffix))
1097 (cond ((< ediff-current-difference 0)
1098 (format " _/%d" ediff-number-of-differences))
1099 ((>= ediff-current-difference ediff-number-of-differences)
1100 (format " $/%d" ediff-number-of-differences))
1101 (t
1102 (format " %d/%d"
1103 (1+ ediff-current-difference)
1104 ediff-number-of-differences)))))
1105
1106(defun ediff-make-wide-control-buffer-id ()
1107 (cond ((< ediff-current-difference 0)
1108 (list (format "%%b At start of %d diffs"
1109 ediff-number-of-differences)))
1110 ((>= ediff-current-difference ediff-number-of-differences)
1111 (list (format "%%b At end of %d diffs"
1112 ediff-number-of-differences)))
1113 (t
1114 (list (format "%%b diff %d of %d"
1115 (1+ ediff-current-difference)
1116 ediff-number-of-differences)))))
1117
1118
1119
1120;; If buff is not live, return nil
1121(defun ediff-get-visible-buffer-window (buff)
1122 (if (ediff-buffer-live-p buff)
1123 (if ediff-xemacs-p
1124 (get-buffer-window buff t)
1125 (get-buffer-window buff 'visible))))
1126
1127;;; Functions to decide when to redraw windows
1128
1129
1130(defun ediff-keep-window-config (control-buf)
1131 (and (eq control-buf (current-buffer))
1132 (/= (buffer-size) 0)
1133 (ediff-eval-in-buffer control-buf
1134 (let ((ctl-wind ediff-control-window)
1135 (A-wind ediff-window-A)
1136 (B-wind ediff-window-B)
1137 (C-wind ediff-window-C))
1138
1139 (and
1140 (ediff-window-visible-p A-wind)
1141 (ediff-window-visible-p B-wind)
1142 ;; if buffer C is defined then take it into account
1143 (or (not ediff-3way-job)
1144 (ediff-window-visible-p C-wind))
1145 (eq (window-buffer A-wind) ediff-buffer-A)
1146 (eq (window-buffer B-wind) ediff-buffer-B)
1147 (or (not ediff-3way-job)
1148 (eq (window-buffer C-wind) ediff-buffer-C))
1149 (string= ediff-window-config-saved
18b5607f 1150 (format "%S%S%S%S%S%S%S"
475f9031 1151 ctl-wind A-wind B-wind C-wind
18b5607f
KH
1152 ediff-split-window-function
1153 (ediff-multiframe-setup-p)
1154 ediff-wide-display-p)))))))
475f9031
KH
1155
1156
1157(provide 'ediff-wind)
1158
1159
1160;;; ediff-wind.el ends here