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