(defvar icon-title-format)
(defvar top-toolbar-height)
(defvar bottom-toolbar-height)
(defvar left-toolbar-height)
(defvar right-toolbar-height)
(defvar left-toolbar-width)
(defvar right-toolbar-width)
(defvar default-menubar)
(defvar top-gutter)
(defvar frame-icon-title-format)
(defvar ediff-diff-status)
(defvar ediff-emacs-p)
(eval-when-compile
(let ((load-path (cons (expand-file-name ".") load-path)))
(or (featurep 'ediff-init)
(load "ediff-init.el" nil nil 'nosuffix))
(or (featurep 'ediff-util)
(load "ediff-util.el" nil nil 'nosuffix))
(or (featurep 'ediff-help)
(load "ediff-help.el" nil nil 'nosuffix))
(or (featurep 'ediff-tbar)
ediff-emacs-p
(load "ediff-tbar.el" 'noerror nil 'nosuffix))
))
(require 'ediff-init)
(if ediff-xemacs-p
(condition-case nil
(require 'ediff-tbar)
(error
(defun ediff-compute-toolbar-width () 0)))
(defun ediff-compute-toolbar-width () 0))
(defgroup ediff-window nil
"Ediff window manipulation."
:prefix "ediff-"
:group 'ediff
:group 'frames)
(defcustom ediff-window-setup-function (if (ediff-window-display-p)
'ediff-setup-windows-multiframe
'ediff-setup-windows-plain)
"*Function called to set up windows.
Ediff provides a choice of two functions: `ediff-setup-windows-plain', for
doing everything in one frame, and `ediff-setup-windows-multiframe',
which sets the control panel in a separate frame. Also, if the latter
function detects that one of the buffers A/B is seen in some other frame,
it will try to keep that buffer in that frame.
If you don't like the two functions provided---write your own one.
The basic guidelines:
1. It should leave the control buffer current and the control window
selected.
2. It should set `ediff-window-A', `ediff-window-B', `ediff-window-C',
and `ediff-control-window' to contain window objects that display
the corresponding buffers.
3. It should accept the following arguments:
buffer-A, buffer-B, buffer-C, control-buffer
Buffer C may not be used in jobs that compare only two buffers.
If you plan to do something fancy, take a close look at how the two
provided functions are written."
:type '(choice (const :tag "Multi Frame" ediff-setup-windows-multiframe)
(const :tag "Single Frame" ediff-setup-windows-plain)
(function :tag "Other function"))
:group 'ediff-window)
(ediff-defvar-local ediff-multiframe nil "")
(ediff-defvar-local ediff-merge-window-share 0.45 "")
(ediff-defvar-local ediff-control-window nil "")
(ediff-defvar-local ediff-window-A nil "")
(ediff-defvar-local ediff-window-B nil "")
(ediff-defvar-local ediff-window-C nil "")
(ediff-defvar-local ediff-window-config-saved "" "")
(defconst ediff-window-alist
'((A . ediff-window-A)
(?A . ediff-window-A)
(B . ediff-window-B)
(?B . ediff-window-B)
(C . ediff-window-C)
(?C . ediff-window-C)))
(defcustom ediff-split-window-function 'split-window-vertically
"*The function used to split the main window between buffer-A and buffer-B.
You can set it to a horizontal split instead of the default vertical split
by setting this variable to `split-window-horizontally'.
You can also have your own function to do fancy splits.
This variable has no effect when buffer-A/B are shown in different frames.
In this case, Ediff will use those frames to display these buffers."
:type 'function
:group 'ediff-window)
(defcustom ediff-merge-split-window-function 'split-window-horizontally
"*The function used to split the main window between buffer-A and buffer-B.
You can set it to a vertical split instead of the default horizontal split
by setting this variable to `split-window-vertically'.
You can also have your own function to do fancy splits.
This variable has no effect when buffer-A/B/C are shown in different frames.
In this case, Ediff will use those frames to display these buffers."
:type 'function
:group 'ediff-window)
(defconst ediff-control-frame-parameters
(list
'(name . "Ediff")
'(minibuffer . nil)
'(user-position . t) '(vertical-scroll-bars . nil) '(scrollbar-width . 0) '(scrollbar-height . 0) '(menu-bar-lines . 0) '(tool-bar-lines . 0) '(left-fringe . 0)
'(right-fringe . 0)
'(auto-lower . nil)
'(auto-raise . t)
'(visibility . nil)
'(width . 1) '(height . 1)
(cons 'top (if (fboundp 'ediff-display-pixel-height)
(1+ (ediff-display-pixel-height))
3000))
(cons 'left (if (fboundp 'ediff-display-pixel-width)
(1+ (ediff-display-pixel-width))
3000))
)
"Frame parameters for displaying Ediff Control Panel.
Used internally---not a user option.")
(ediff-defvar-local ediff-mouse-pixel-position nil "")
(defvar ediff-mouse-pixel-threshold 30
"If the user moves mouse more than this many pixels, Ediff won't warp mouse into control window.")
(defcustom ediff-grab-mouse t
"*If t, Ediff will always grab the mouse and put it in the control frame.
If 'maybe, Ediff will do it sometimes, but not after operations that require
relatively long time. If nil, the mouse will be entirely user's
responsibility."
:type 'boolean
:group 'ediff-window)
(defcustom ediff-control-frame-position-function 'ediff-make-frame-position
"Function to call to determine the desired location for the control panel.
Expects three parameters: the control buffer, the desired width and height
of the control frame. It returns an association list
of the form \(\(top . <position>\) \(left . <position>\)\)"
:type 'function
:group 'ediff-window)
(defcustom ediff-control-frame-upward-shift 42
"*The upward shift of control frame from the top of buffer A's frame.
Measured in pixels.
This is used by the default control frame positioning function,
`ediff-make-frame-position'. This variable is provided for easy
customization of the default control frame positioning."
:type 'integer
:group 'ediff-window)
(defcustom ediff-narrow-control-frame-leftward-shift (if ediff-xemacs-p 7 3)
"*The leftward shift of control frame from the right edge of buf A's frame.
Measured in characters.
This is used by the default control frame positioning function,
`ediff-make-frame-position' to adjust the position of the control frame
when it shows the short menu. This variable is provided for easy
customization of the default."
:type 'integer
:group 'ediff-window)
(defcustom ediff-wide-control-frame-rightward-shift 7
"*The rightward shift of control frame from the left edge of buf A's frame.
Measured in characters.
This is used by the default control frame positioning function,
`ediff-make-frame-position' to adjust the position of the control frame
when it shows the full menu. This variable is provided for easy
customization of the default."
:type 'integer
:group 'ediff-window)
(ediff-defvar-local ediff-wide-display-p nil "")
(ediff-defvar-local ediff-wide-display-orig-parameters nil
"Frame parameters to be restored when the user wants to toggle the wide
display off.")
(ediff-defvar-local ediff-wide-display-frame nil
"Frame to be used for wide display.")
(ediff-defvar-local ediff-make-wide-display-function 'ediff-make-wide-display
"The value is a function that is called to create a wide display.
The function is called without arguments. It should resize the frame in
which buffers A, B, and C are to be displayed, and it should save the old
frame parameters in `ediff-wide-display-orig-parameters'.
The variable `ediff-wide-display-frame' should be set to contain
the frame used for the wide display.")
(ediff-defvar-local ediff-control-frame nil "")
(defcustom ediff-prefer-iconified-control-frame nil
"*If t, keep control panel iconified when help message is off.
This has effect only on a windowing system.
If t, hitting `?' to toggle control panel off iconifies it.
This is only useful in Emacs and only for certain kinds of window managers,
such as TWM and its derivatives, since the window manager must permit
keyboard input to go into icons. XEmacs completely ignores keyboard input
into icons, regardless of the window manager."
:type 'boolean
:group 'ediff-window)
(defun ediff-get-window-by-clicking (wind prev-wind wind-number)
(let (event)
(message
"Select windows by clicking. Please click on Window %d " wind-number)
(while (not (ediff-mouse-event-p (setq event (ediff-read-event))))
(if (sit-for 1) (beep 1))
(message "Please click on Window %d " wind-number))
(ediff-read-event) (setq wind (ediff-cond-compile-for-xemacs-or-emacs
(event-window event) (posn-window (event-start event)) )
)
))
(defun ediff-select-lowest-window ()
(ediff-cond-compile-for-xemacs-or-emacs
(select-window (frame-lowest-window)) (let* ((lowest-window (selected-window))
(bottom-edge (car (cdr (cdr (cdr (window-edges))))))
(last-window (save-excursion
(other-window -1) (selected-window)))
(window-search t))
(while window-search
(let* ((this-window (next-window))
(next-bottom-edge
(car (cdr (cdr (cdr (window-edges this-window)))))))
(if (< bottom-edge next-bottom-edge)
(progn
(setq bottom-edge next-bottom-edge)
(setq lowest-window this-window)))
(select-window this-window)
(if (eq last-window this-window)
(progn
(select-window lowest-window)
(setq window-search nil))))))
))
(defun ediff-setup-windows (buffer-A buffer-B buffer-C control-buffer)
(run-hooks 'ediff-before-setup-windows-hook)
(if (eq (selected-window) (minibuffer-window))
(other-window 1))
(or (ediff-window-display-p)
(setq ediff-window-setup-function 'ediff-setup-windows-plain))
(or (ediff-keep-window-config control-buffer)
(funcall
(ediff-with-current-buffer control-buffer ediff-window-setup-function)
buffer-A buffer-B buffer-C control-buffer))
(run-hooks 'ediff-after-setup-windows-hook))
(defun ediff-setup-windows-plain (buffer-A buffer-B buffer-C control-buffer)
(ediff-with-current-buffer control-buffer
(setq ediff-multiframe nil))
(if ediff-merge-job
(ediff-setup-windows-plain-merge
buffer-A buffer-B buffer-C control-buffer)
(ediff-setup-windows-plain-compare
buffer-A buffer-B buffer-C control-buffer)))
(defun ediff-setup-windows-plain-merge (buf-A buf-B buf-C control-buffer)
(ediff-destroy-control-frame control-buffer)
(let ((window-min-height 1)
split-window-function
merge-window-share merge-window-lines
wind-A wind-B wind-C)
(ediff-with-current-buffer control-buffer
(setq merge-window-share ediff-merge-window-share
split-window-function ediff-split-window-function))
(delete-other-windows)
(split-window-vertically)
(ediff-select-lowest-window)
(ediff-setup-control-buffer control-buffer)
(other-window 1)
(setq merge-window-lines
(max 2 (round (* (window-height) merge-window-share))))
(switch-to-buffer buf-A)
(setq wind-A (selected-window))
(split-window-vertically (max 2 (- (window-height) merge-window-lines)))
(if (eq (selected-window) wind-A)
(other-window 1))
(setq wind-C (selected-window))
(switch-to-buffer buf-C)
(select-window wind-A)
(funcall split-window-function)
(if (eq (selected-window) wind-A)
(other-window 1))
(switch-to-buffer buf-B)
(setq wind-B (selected-window))
(ediff-with-current-buffer control-buffer
(setq ediff-window-A wind-A
ediff-window-B wind-B
ediff-window-C wind-C))
(ediff-select-lowest-window)
(ediff-setup-control-buffer control-buffer)
))
(defun ediff-setup-windows-plain-compare (buf-A buf-B buf-C control-buffer)
(ediff-destroy-control-frame control-buffer)
(let ((window-min-height 1)
split-window-function wind-width-or-height
three-way-comparison
wind-A-start wind-B-start wind-A wind-B wind-C)
(ediff-with-current-buffer control-buffer
(setq wind-A-start (ediff-overlay-start
(ediff-get-value-according-to-buffer-type
'A ediff-narrow-bounds))
wind-B-start (ediff-overlay-start
(ediff-get-value-according-to-buffer-type
'B ediff-narrow-bounds))
split-window-function ediff-split-window-function
three-way-comparison ediff-3way-comparison-job))
(delete-other-windows)
(split-window-vertically)
(ediff-select-lowest-window)
(ediff-setup-control-buffer control-buffer)
(other-window 1)
(switch-to-buffer buf-A)
(setq wind-A (selected-window))
(if three-way-comparison
(setq wind-width-or-height
(/ (if (eq split-window-function 'split-window-vertically)
(window-height wind-A)
(window-width wind-A))
3)))
(funcall split-window-function wind-width-or-height)
(if (eq (selected-window) wind-A)
(other-window 1))
(switch-to-buffer buf-B)
(setq wind-B (selected-window))
(if three-way-comparison
(progn
(funcall split-window-function) (if (eq (selected-window) wind-B)
(other-window 1))
(switch-to-buffer buf-C)
(setq wind-C (selected-window))))
(ediff-with-current-buffer control-buffer
(setq ediff-window-A wind-A
ediff-window-B wind-B
ediff-window-C wind-C))
(if ediff-windows-job
(progn
(set-window-start wind-A wind-A-start)
(set-window-start wind-B wind-B-start)))
(ediff-select-lowest-window)
(ediff-setup-control-buffer control-buffer)
))
(defun ediff-setup-windows-multiframe (buf-A buf-B buf-C control-buf)
(ediff-with-current-buffer control-buf
(setq ediff-multiframe t))
(if ediff-merge-job
(ediff-setup-windows-multiframe-merge buf-A buf-B buf-C control-buf)
(ediff-setup-windows-multiframe-compare buf-A buf-B buf-C control-buf)))
(defun ediff-setup-windows-multiframe-merge (buf-A buf-B buf-C control-buf)
(ediff-skip-unsuitable-frames 'ok-unsplittable)
(let* ((window-min-height 1)
(wind-A (ediff-get-visible-buffer-window buf-A))
(wind-B (ediff-get-visible-buffer-window buf-B))
(wind-C (ediff-get-visible-buffer-window buf-C))
(frame-A (if wind-A (window-frame wind-A)))
(frame-B (if wind-B (window-frame wind-B)))
(frame-C (if wind-C (window-frame wind-C)))
(force-one-frame
(ediff-with-current-buffer control-buf ediff-wide-display-p))
(split-window-function
(ediff-with-current-buffer control-buf ediff-split-window-function))
(orig-wind (selected-window))
(orig-frame (selected-frame))
(use-same-frame (or force-one-frame
(eq frame-A (or frame-C orig-frame))
(eq frame-B (or frame-C orig-frame))
(not (frame-live-p frame-A))
(not (frame-live-p frame-B))
(not (ediff-window-ok-for-display wind-A))
(not (ediff-window-ok-for-display wind-B))
(and (eq frame-A frame-B)
(not (frame-live-p frame-C)))
))
(use-same-frame-for-AB (and (not use-same-frame)
(eq frame-A frame-B)))
(merge-window-share (ediff-with-current-buffer control-buf
ediff-merge-window-share))
merge-window-lines
designated-minibuffer-frame
done-A done-B done-C)
(if (and (window-live-p wind-A)
(null use-same-frame) (null use-same-frame-for-AB))
(progn (select-window wind-A)
(delete-other-windows)
(setq wind-A (selected-window))
(setq done-A t)))
(if (and (window-live-p wind-B)
(null use-same-frame) (null use-same-frame-for-AB))
(progn (select-window wind-B)
(delete-other-windows)
(setq wind-B (selected-window))
(setq done-B t)))
(if (and (window-live-p wind-C)
(ediff-window-ok-for-display wind-C)
(null use-same-frame)) (progn
(select-window wind-C)
(delete-other-windows)
(setq wind-C (selected-window))
(setq done-C t)))
(if (and use-same-frame-for-AB (window-live-p wind-A))
(progn
(select-window wind-A)
(delete-other-windows)
(setq wind-A (selected-window))
(funcall split-window-function)
(if (eq (selected-window) wind-A)
(other-window 1))
(switch-to-buffer buf-B)
(setq wind-B (selected-window))
(setq done-A t
done-B t)))
(if use-same-frame
(let ((window-min-height 1))
(if (and (eq frame-A frame-B)
(eq frame-B frame-C)
(frame-live-p frame-A))
(select-frame frame-A)
(ediff-skip-unsuitable-frames))
(delete-other-windows)
(setq merge-window-lines
(max 2 (round (* (window-height) merge-window-share))))
(switch-to-buffer buf-A)
(setq wind-A (selected-window))
(split-window-vertically
(max 2 (- (window-height) merge-window-lines)))
(if (eq (selected-window) wind-A)
(other-window 1))
(setq wind-C (selected-window))
(switch-to-buffer buf-C)
(select-window wind-A)
(funcall split-window-function)
(if (eq (selected-window) wind-A)
(other-window 1))
(switch-to-buffer buf-B)
(setq wind-B (selected-window))
(setq done-A t
done-B t
done-C t)
))
(or done-A (progn
(select-window orig-wind)
(delete-other-windows)
(switch-to-buffer buf-A)
(setq wind-A (selected-window))
))
(or done-B (progn
(select-window orig-wind)
(delete-other-windows)
(switch-to-buffer buf-B)
(setq wind-B (selected-window))
))
(or done-C (progn
(select-window orig-wind)
(delete-other-windows)
(switch-to-buffer buf-C)
(setq wind-C (selected-window))
))
(ediff-with-current-buffer control-buf
(setq ediff-window-A wind-A
ediff-window-B wind-B
ediff-window-C wind-C)
(setq frame-A (window-frame ediff-window-A)
designated-minibuffer-frame
(window-frame (minibuffer-window frame-A))))
(ediff-setup-control-frame control-buf designated-minibuffer-frame)
))
(defun ediff-setup-windows-multiframe-compare (buf-A buf-B buf-C control-buf)
(ediff-skip-unsuitable-frames 'ok-unsplittable)
(let* ((window-min-height 1)
(wind-A (ediff-get-visible-buffer-window buf-A))
(wind-B (ediff-get-visible-buffer-window buf-B))
(wind-C (ediff-get-visible-buffer-window buf-C))
(frame-A (if wind-A (window-frame wind-A)))
(frame-B (if wind-B (window-frame wind-B)))
(frame-C (if wind-C (window-frame wind-C)))
(ctl-frame-exists-p (ediff-with-current-buffer control-buf
(frame-live-p ediff-control-frame)))
(force-one-frame
(ediff-with-current-buffer control-buf ediff-wide-display-p))
(split-window-function
(ediff-with-current-buffer control-buf ediff-split-window-function))
(three-way-comparison
(ediff-with-current-buffer control-buf ediff-3way-comparison-job))
(orig-wind (selected-window))
(use-same-frame (or force-one-frame
(eq frame-A frame-B)
(not (ediff-window-ok-for-display wind-A))
(not (ediff-window-ok-for-display wind-B))
(if three-way-comparison
(or (eq frame-A frame-C)
(eq frame-B frame-C)
(not (ediff-window-ok-for-display wind-C))
(not (frame-live-p frame-A))
(not (frame-live-p frame-B))
(not (frame-live-p frame-C))))
(and (not (frame-live-p frame-B))
(or ctl-frame-exists-p
(eq frame-A (selected-frame))))
(and (not (frame-live-p frame-A))
(or ctl-frame-exists-p
(eq frame-B (selected-frame))))))
wind-A-start wind-B-start
designated-minibuffer-frame
done-A done-B done-C)
(ediff-with-current-buffer control-buf
(setq wind-A-start (ediff-overlay-start
(ediff-get-value-according-to-buffer-type
'A ediff-narrow-bounds))
wind-B-start (ediff-overlay-start
(ediff-get-value-according-to-buffer-type
'B ediff-narrow-bounds))))
(if (and (window-live-p wind-A) (null use-same-frame)) (progn
(select-window wind-A) (delete-other-windows)
(setq wind-A (selected-window))
(setq done-A t)))
(if (and (window-live-p wind-B) (null use-same-frame)) (progn
(select-window wind-B) (delete-other-windows)
(setq wind-B (selected-window))
(setq done-B t)))
(if (and (window-live-p wind-C) (null use-same-frame)) (progn
(select-window wind-C) (delete-other-windows)
(setq wind-C (selected-window))
(setq done-C t)))
(if use-same-frame
(let (wind-width-or-height) (if (and (eq frame-A frame-B) (frame-live-p frame-A))
(select-frame frame-A)
(ediff-skip-unsuitable-frames))
(delete-other-windows)
(switch-to-buffer buf-A)
(setq wind-A (selected-window))
(if three-way-comparison
(setq wind-width-or-height
(/
(if (eq split-window-function 'split-window-vertically)
(window-height wind-A)
(window-width wind-A))
3)))
(funcall split-window-function wind-width-or-height)
(if (eq (selected-window) wind-A)
(other-window 1))
(switch-to-buffer buf-B)
(setq wind-B (selected-window))
(if three-way-comparison
(progn
(funcall split-window-function) (if (memq (selected-window) (list wind-A wind-B))
(other-window 1))
(switch-to-buffer buf-C)
(setq wind-C (selected-window))))
(setq done-A t
done-B t
done-C t)
))
(or done-A (progn
(select-window orig-wind)
(delete-other-windows)
(switch-to-buffer buf-A)
(setq wind-A (selected-window))
))
(or done-B (progn
(select-window orig-wind)
(delete-other-windows)
(switch-to-buffer buf-B)
(setq wind-B (selected-window))
))
(if three-way-comparison
(or done-C (progn
(select-window orig-wind)
(delete-other-windows)
(switch-to-buffer buf-C)
(setq wind-C (selected-window))
)))
(ediff-with-current-buffer control-buf
(setq ediff-window-A wind-A
ediff-window-B wind-B
ediff-window-C wind-C)
(setq frame-A (window-frame ediff-window-A)
designated-minibuffer-frame
(window-frame (minibuffer-window frame-A))))
(if ediff-windows-job
(progn
(set-window-start wind-A wind-A-start)
(set-window-start wind-B wind-B-start)))
(ediff-setup-control-frame control-buf designated-minibuffer-frame)
))
(defun ediff-skip-unsuitable-frames (&optional ok-unsplittable)
(if (ediff-window-display-p)
(let ((wind-frame (window-frame (selected-window)))
seen-windows)
(while (and (not (memq (selected-window) seen-windows))
(or
(ediff-frame-has-dedicated-windows wind-frame)
(ediff-frame-iconified-p wind-frame)
(< (frame-height wind-frame)
(* 3 window-min-height))
(if ok-unsplittable
nil
(ediff-frame-unsplittable-p wind-frame))))
(setq seen-windows (cons (selected-window) seen-windows))
(other-window 1 t)
(setq wind-frame (window-frame (selected-window)))
)
(if (memq (selected-window) seen-windows)
(setq wind-frame (make-frame '((unsplittable)))))
(select-frame wind-frame)
)))
(defun ediff-frame-has-dedicated-windows (frame)
(let (ans)
(walk-windows
(lambda (wind) (if (window-dedicated-p wind)
(setq ans t)))
'ignore-minibuffer
frame)
ans))
(defun ediff-window-ok-for-display (wind)
(and
(window-live-p wind)
(or
(eq wind (next-window wind 'ignore-minibuffer (window-frame wind)))
(not (ediff-frame-has-dedicated-windows (window-frame wind)))
)))
(defun ediff-setup-control-frame (ctl-buffer designated-minibuffer-frame)
(let ((window-min-height 1)
ctl-frame-iconified-p dont-iconify-ctl-frame deiconify-ctl-frame
ctl-frame old-ctl-frame lines
fheight fwidth adjusted-parameters)
(ediff-with-current-buffer ctl-buffer
(ediff-cond-compile-for-xemacs-or-emacs
(when (featurep 'menubar) (set-buffer-menubar nil)) nil )
(run-hooks 'ediff-before-setup-control-frame-hook))
(setq old-ctl-frame (ediff-with-current-buffer ctl-buffer ediff-control-frame))
(ediff-with-current-buffer ctl-buffer
(setq ctl-frame (if (frame-live-p old-ctl-frame)
old-ctl-frame
(make-frame ediff-control-frame-parameters))
ediff-control-frame ctl-frame)
(condition-case nil
(ediff-cond-compile-for-xemacs-or-emacs
nil (when (face-attribute 'mode-line :box)
(set-face-attribute 'mode-line ctl-frame :box nil))
)
(error))
)
(setq ctl-frame-iconified-p (ediff-frame-iconified-p ctl-frame))
(select-frame ctl-frame)
(if (window-dedicated-p (selected-window))
()
(delete-other-windows)
(switch-to-buffer ctl-buffer))
(ediff-with-current-buffer ctl-buffer
(make-local-variable 'frame-title-format)
(make-local-variable 'frame-icon-title-format) (make-local-variable 'icon-title-format))
(ediff-setup-control-buffer ctl-buffer)
(setq dont-iconify-ctl-frame
(not (string= ediff-help-message ediff-brief-help-message)))
(setq deiconify-ctl-frame
(and (eq this-command 'ediff-toggle-help)
dont-iconify-ctl-frame))
(setq lines (1+ (count-lines (point-min) (point-max)))
fheight lines
fwidth (max (+ (ediff-help-message-line-length) 2)
(ediff-compute-toolbar-width))
adjusted-parameters
(list
(cons 'minibuffer
(minibuffer-window
designated-minibuffer-frame))
(cons 'width fwidth)
(cons 'height fheight)
(cons 'user-position t)
))
(setq adjusted-parameters
(cons (if ediff-use-long-help-message
'(auto-raise . nil)
'(auto-raise . t))
adjusted-parameters))
(if (ediff-has-toolbar-support-p)
(ediff-cond-compile-for-xemacs-or-emacs
(progn (if (ediff-has-gutter-support-p)
(set-specifier top-gutter (list ctl-frame nil)))
(sit-for 0)
(set-specifier top-toolbar-height (list ctl-frame 0))
(set-specifier left-toolbar-width (list ctl-frame 0))
(set-specifier right-toolbar-width (list ctl-frame 0))
)
nil )
)
(if (memq system-type '(emx windows-nt windows-95))
(modify-frame-parameters ctl-frame adjusted-parameters))
(ediff-make-bottom-toolbar ctl-frame)
(goto-char (point-min))
(modify-frame-parameters ctl-frame adjusted-parameters)
(make-frame-visible ctl-frame)
(select-frame ctl-frame)
(ediff-refresh-control-frame)
(cond ((and ediff-prefer-iconified-control-frame
(not ctl-frame-iconified-p) (not dont-iconify-ctl-frame))
(iconify-frame ctl-frame))
((or deiconify-ctl-frame (not ctl-frame-iconified-p))
(raise-frame ctl-frame)))
(set-window-dedicated-p (selected-window) t)
(modify-frame-parameters
ctl-frame
(funcall ediff-control-frame-position-function ctl-buffer fwidth fheight))
(if (ediff-window-display-p)
(let ((count 7))
(sit-for .1)
(while (and (not (frame-visible-p ctl-frame)) (> count 0))
(setq count (1- count))
(sit-for .3))))
(or (ediff-frame-iconified-p ctl-frame)
(ediff-reset-mouse ctl-frame
(or (eq this-command 'ediff-quit)
(not (eq ediff-grab-mouse t)))))
(if ediff-xemacs-p
(ediff-with-current-buffer ctl-buffer
(ediff-cond-compile-for-xemacs-or-emacs
(make-local-hook 'select-frame-hook) nil )
(add-hook
'select-frame-hook 'ediff-xemacs-select-frame-hook nil 'local)
))
(ediff-with-current-buffer ctl-buffer
(run-hooks 'ediff-after-setup-control-frame-hook))
))
(defun ediff-destroy-control-frame (ctl-buffer)
(ediff-with-current-buffer ctl-buffer
(if (and (ediff-window-display-p) (frame-live-p ediff-control-frame))
(let ((ctl-frame ediff-control-frame))
(ediff-cond-compile-for-xemacs-or-emacs
(when (featurep 'menubar)
(set-buffer-menubar default-menubar)) nil )
(setq ediff-control-frame nil)
(delete-frame ctl-frame)
)))
(ediff-skip-unsuitable-frames)
)
(defun ediff-make-frame-position (ctl-buffer ctl-frame-width ctl-frame-height)
(ediff-with-current-buffer ctl-buffer
(let* ((frame-A (window-frame ediff-window-A))
(frame-A-parameters (frame-parameters frame-A))
(frame-A-top (eval (cdr (assoc 'top frame-A-parameters))))
(frame-A-left (eval (cdr (assoc 'left frame-A-parameters))))
(frame-A-width (frame-width frame-A))
(ctl-frame ediff-control-frame)
horizontal-adjustment upward-adjustment
ctl-frame-top ctl-frame-left)
(setq horizontal-adjustment (* 2 ediff-control-buffer-number)
upward-adjustment (* -14 ediff-control-buffer-number))
(setq ctl-frame-top
(- frame-A-top upward-adjustment ediff-control-frame-upward-shift)
ctl-frame-left
(+ frame-A-left
(if ediff-use-long-help-message
(* (ediff-frame-char-width ctl-frame)
(+ ediff-wide-control-frame-rightward-shift
horizontal-adjustment))
(- (* frame-A-width (ediff-frame-char-width frame-A))
(* (ediff-frame-char-width ctl-frame)
(+ ctl-frame-width
ediff-narrow-control-frame-leftward-shift
horizontal-adjustment))))))
(setq ctl-frame-top
(min ctl-frame-top
(- (ediff-display-pixel-height)
(* 2 ctl-frame-height
(ediff-frame-char-height ctl-frame))))
ctl-frame-left
(min ctl-frame-left
(- (ediff-display-pixel-width)
(* ctl-frame-width (ediff-frame-char-width ctl-frame)))))
(setq ctl-frame-top (max ctl-frame-top 1)
ctl-frame-left (max ctl-frame-left 1))
(list (cons 'top ctl-frame-top)
(cons 'left ctl-frame-left))
)))
(defun ediff-xemacs-select-frame-hook ()
(if (and (equal (selected-frame) ediff-control-frame)
(not ediff-use-long-help-message))
(raise-frame ediff-control-frame)))
(defun ediff-make-wide-display ()
"Construct an alist of parameters for the wide display.
Saves the old frame parameters in `ediff-wide-display-orig-parameters'.
The frame to be resized is kept in `ediff-wide-display-frame'.
This function modifies only the left margin and the width of the display.
It assumes that it is called from within the control buffer."
(if (not (fboundp 'ediff-display-pixel-width))
(error "Can't determine display width"))
(let* ((frame-A (window-frame ediff-window-A))
(frame-A-params (frame-parameters frame-A))
(cw (ediff-frame-char-width frame-A))
(wd (- (/ (ediff-display-pixel-width) cw) 5)))
(setq ediff-wide-display-orig-parameters
(list (cons 'left (max 0 (eval (cdr (assoc 'left frame-A-params)))))
(cons 'width (cdr (assoc 'width frame-A-params))))
ediff-wide-display-frame frame-A)
(modify-frame-parameters
frame-A `((left . ,cw) (width . ,wd) (user-position t)))))
(defun ediff-refresh-mode-lines ()
(let (buf-A-state-diff buf-B-state-diff buf-C-state-diff buf-C-state-merge)
(if (ediff-valid-difference-p)
(setq
buf-C-state-diff (ediff-get-state-of-diff ediff-current-difference 'C)
buf-C-state-merge (ediff-get-state-of-merge ediff-current-difference)
buf-A-state-diff (ediff-get-state-of-diff ediff-current-difference 'A)
buf-B-state-diff (ediff-get-state-of-diff ediff-current-difference 'B)
buf-A-state-diff (if buf-A-state-diff
(format "[%s] " buf-A-state-diff)
"")
buf-B-state-diff (if buf-B-state-diff
(format "[%s] " buf-B-state-diff)
"")
buf-C-state-diff (if (and (ediff-buffer-live-p ediff-buffer-C)
(or buf-C-state-diff buf-C-state-merge))
(format "[%s%s%s] "
(or buf-C-state-diff "")
(if buf-C-state-merge
(concat " " buf-C-state-merge)
"")
(if (ediff-get-state-of-ancestor
ediff-current-difference)
" AncestorEmpty"
"")
)
""))
(setq buf-A-state-diff ""
buf-B-state-diff ""
buf-C-state-diff ""))
(setq mode-line-format
(if (ediff-narrow-control-frame-p)
(list " " mode-line-buffer-identification)
(list "-- " mode-line-buffer-identification " Quick Help")))
(setq mode-line-buffer-identification
(if (ediff-narrow-control-frame-p)
(ediff-make-narrow-control-buffer-id 'skip-name)
(ediff-make-wide-control-buffer-id)))
(force-mode-line-update)
(if (and (ediff-window-display-p) (frame-live-p ediff-control-frame))
(ediff-refresh-control-frame))
(ediff-with-current-buffer ediff-buffer-A
(setq ediff-diff-status buf-A-state-diff)
(ediff-strip-mode-line-format)
(setq mode-line-format
(list " A: " 'ediff-diff-status mode-line-format))
(force-mode-line-update))
(ediff-with-current-buffer ediff-buffer-B
(setq ediff-diff-status buf-B-state-diff)
(ediff-strip-mode-line-format)
(setq mode-line-format
(list " B: " 'ediff-diff-status mode-line-format))
(force-mode-line-update))
(if ediff-3way-job
(ediff-with-current-buffer ediff-buffer-C
(setq ediff-diff-status buf-C-state-diff)
(ediff-strip-mode-line-format)
(setq mode-line-format
(list " C: " 'ediff-diff-status mode-line-format))
(force-mode-line-update)))
(if (ediff-buffer-live-p ediff-ancestor-buffer)
(ediff-with-current-buffer ediff-ancestor-buffer
(ediff-strip-mode-line-format)
(setq mode-line-format
(list " Ancestor: "
(cond ((not (stringp buf-C-state-merge))
"")
((string-match "prefer-A" buf-C-state-merge)
"[=diff(B)] ")
((string-match "prefer-B" buf-C-state-merge)
"[=diff(A)] ")
(t ""))
mode-line-format))))
))
(defun ediff-refresh-control-frame ()
(if ediff-emacs-p
(modify-frame-parameters
ediff-control-frame
(list (cons 'title (ediff-make-base-title))
(cons 'icon-name (ediff-make-narrow-control-buffer-id))
))
(setq frame-title-format (ediff-make-base-title)
frame-icon-title-format (ediff-make-narrow-control-buffer-id))
(modify-frame-parameters ediff-control-frame '(()))))
(defun ediff-make-narrow-control-buffer-id (&optional skip-name)
(concat
(if skip-name
" "
(ediff-make-base-title))
(cond ((< ediff-current-difference 0)
(format " _/%d" ediff-number-of-differences))
((>= ediff-current-difference ediff-number-of-differences)
(format " $/%d" ediff-number-of-differences))
(t
(format " %d/%d"
(1+ ediff-current-difference)
ediff-number-of-differences)))))
(defun ediff-make-base-title ()
(concat
(cdr (assoc 'name ediff-control-frame-parameters))
ediff-control-buffer-suffix))
(defun ediff-make-wide-control-buffer-id ()
(cond ((< ediff-current-difference 0)
(list (format "%%b At start of %d diffs"
ediff-number-of-differences)))
((>= ediff-current-difference ediff-number-of-differences)
(list (format "%%b At end of %d diffs"
ediff-number-of-differences)))
(t
(list (format "%%b diff %d of %d"
(1+ ediff-current-difference)
ediff-number-of-differences)))))
(defun ediff-get-visible-buffer-window (buff)
(if (ediff-buffer-live-p buff)
(if ediff-xemacs-p
(get-buffer-window buff t)
(get-buffer-window buff 'visible))))
(defun ediff-keep-window-config (control-buf)
(and (eq control-buf (current-buffer))
(/= (buffer-size) 0)
(ediff-with-current-buffer control-buf
(let ((ctl-wind ediff-control-window)
(A-wind ediff-window-A)
(B-wind ediff-window-B)
(C-wind ediff-window-C))
(and
(ediff-window-visible-p A-wind)
(ediff-window-visible-p B-wind)
(or (not ediff-3way-job)
(ediff-window-visible-p C-wind))
(eq (window-buffer A-wind) ediff-buffer-A)
(eq (window-buffer B-wind) ediff-buffer-B)
(or (not ediff-3way-job)
(eq (window-buffer C-wind) ediff-buffer-C))
(string= ediff-window-config-saved
(format "%S%S%S%S%S%S%S"
ctl-wind A-wind B-wind C-wind
ediff-split-window-function
(ediff-multiframe-setup-p)
ediff-wide-display-p)))))))
(provide 'ediff-wind)