Function: ediff-setup-windows-multiframe-merge

ediff-setup-windows-multiframe-merge is a byte-compiled function defined in ediff-wind.el.gz.

Signature

(ediff-setup-windows-multiframe-merge BUF-A BUF-B BUF-C CONTROL-BUF)

Source Code

;; Defined in /usr/src/emacs/lisp/vc/ediff-wind.el.gz
(defun ediff-setup-windows-multiframe-merge (buf-A buf-B buf-C control-buf)
  ;; Algorithm:
  ;;   1. Never use frames that have dedicated windows in them---it is bad to
  ;;      destroy dedicated windows.
  ;;   2. If A and B are in the same frame but C's frame is different--- use one
  ;;      frame for A and B and use a separate frame for C.
  ;;   3. If C's frame is non-existent, then: if the first suitable
  ;;      non-dedicated frame  is different from A&B's, then use it for C.
  ;;      Otherwise, put A,B, and C in one frame.
  ;;   4. If buffers A, B, C are is separate frames, use them to display these
  ;;      buffers.

  ;;   Skip dedicated or iconified frames.
  ;;   Unsplittable frames are taken care of later.
  ;; (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))
	 (buf-Ancestor (with-current-buffer control-buf
                         ediff-ancestor-buffer))
	 (wind-Ancestor (ediff-get-visible-buffer-window buf-Ancestor))
	 (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)))
	 (frame-Ancestor (if wind-Ancestor (window-frame wind-Ancestor)))
	 ;; on wide display, do things in one frame
	 (force-one-frame
	  (with-current-buffer control-buf ediff-wide-display-p))
	 ;; this lets us have local versions of ediff-split-window-function
	 (split-window-function
	  (with-current-buffer control-buf ediff-split-window-function))
	 (orig-wind (selected-window))
	 (orig-frame (selected-frame))
	 (use-same-frame (or force-one-frame
			     ;; A and C must be in one frame
			     (eq frame-A (or frame-C orig-frame))
			     ;; B and C must be in one frame
			     (eq frame-B (or frame-C orig-frame))
			     ;; A or B is not visible
			     (not (frame-live-p frame-A))
			     (not (frame-live-p frame-B))
			     ;; A or B is not suitable for display
			     (not (ediff-window-ok-for-display wind-A))
			     (not (ediff-window-ok-for-display wind-B))
			     ;; A and B in the same frame, and no good frame
			     ;; for C
			     (and (eq frame-A frame-B)
				  (not (frame-live-p frame-C)))
			     ))
	 ;; use-same-frame-for-AB implies wind A and B are ok for display
	 (use-same-frame-for-AB (and (not use-same-frame)
				     (eq frame-A frame-B)))
	 (merge-window-share (with-current-buffer control-buf
			       ediff-merge-window-share))
	 merge-window-lines
	 designated-minibuffer-frame ; ediff-merge-with-ancestor-job
     (with-Ancestor-p (with-current-buffer control-buf
                        ediff-merge-with-ancestor-job))
     (done-Ancestor (not with-Ancestor-p))
	 done-A done-B done-C)

    ;; buf-A on its own
    (if (and (window-live-p wind-A)
	     (null use-same-frame) ; implies wind-A is suitable
	     (null use-same-frame-for-AB))
	(progn ; buf A on its own
	  ;; buffer buf-A is seen in live wind-A
	  (select-window wind-A)
	  (delete-other-windows)
	  (setq wind-A (selected-window))
	  (setq done-A t)))

    ;; buf-B on its own
    (if (and (window-live-p wind-B)
	     (null use-same-frame) ; implies wind-B is suitable
	     (null use-same-frame-for-AB))
	(progn ; buf B on its own
	  ;; buffer buf-B is seen in live wind-B
	  (select-window wind-B)
	  (delete-other-windows)
	  (setq wind-B (selected-window))
	  (setq done-B t)))

    ;; buf-C on its own
    (if (and (window-live-p wind-C)
	     (ediff-window-ok-for-display wind-C)
	     (null use-same-frame)) ; buf C on its own
	(progn
	  ;; buffer buf-C is seen in live wind-C
	  (select-window wind-C)
	  (delete-other-windows)
	  (setq wind-C (selected-window))
	  (setq done-C t)))

    ;; buf-Ancestor on its own
    (if (and ediff-show-ancestor
             with-Ancestor-p
             (window-live-p wind-Ancestor)
             (ediff-window-ok-for-display wind-Ancestor)
             (null use-same-frame)) ; buf Ancestor on its own
        (progn
          ;; buffer buf-Ancestor is seen in live wind-Ancestor
          (select-window wind-Ancestor)
          (delete-other-windows)
          (setq wind-Ancestor (selected-window))
          (setq done-Ancestor t)))

    (if (and use-same-frame-for-AB  ; implies wind A and B are suitable
	     (window-live-p wind-A))
	(progn
	  ;; wind-A must already be displaying buf-A
	  (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)
		   (eq frame-C frame-Ancestor)
		   (frame-live-p frame-A))
	      (select-frame frame-A)
	    ;; avoid dedicated and non-splittable windows
	    (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)

      (when (and ediff-show-ancestor with-Ancestor-p)
        (select-window wind-C)
        (funcall split-window-function)
        (if (eq (selected-window) wind-C)
            (other-window 1))
        (switch-to-buffer buf-Ancestor)
        (setq wind-Ancestor (selected-window)))

	  (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
        done-Ancestor t)))

    (or done-A  ; Buf A to be set in its own frame,
	      ;;; or it was set before because use-same-frame = 1
	(progn
	  ;; Buf-A was not set up yet as it wasn't visible,
	  ;; and use-same-frame = nil, use-same-frame-for-AB = nil
	  (select-window orig-wind)
	  (delete-other-windows)
	  (switch-to-buffer buf-A)
	  (setq wind-A (selected-window))
	  ))
    (or done-B  ; Buf B to be set in its own frame,
	      ;;; or it was set before because use-same-frame = 1
	(progn
	  ;; Buf-B was not set up yet as it wasn't visible
	  ;; and use-same-frame = nil, use-same-frame-for-AB = nil
	  (select-window orig-wind)
	  (delete-other-windows)
	  (switch-to-buffer buf-B)
	  (setq wind-B (selected-window))
	  ))

    (or done-C  ; Buf C to be set in its own frame,
	      ;;; or it was set before because use-same-frame = 1
	(progn
	  ;; Buf-C was not set up yet as it wasn't visible
	  ;; and use-same-frame = nil
	  (select-window orig-wind)
	  (delete-other-windows)
	  (switch-to-buffer buf-C)
	  (setq wind-C (selected-window))
	  ))

    (or done-Ancestor  ; Buf Ancestor to be set in its own frame,
        (not ediff-show-ancestor)
	      ;;; or it was set before because use-same-frame = 1
        (progn
          ;; Buf-Ancestor was not set up yet as it wasn't visible
          ;; and use-same-frame = nil
          (select-window orig-wind)
          (delete-other-windows)
          (switch-to-buffer buf-Ancestor)
          (setq wind-Ancestor (selected-window))))

    (with-current-buffer control-buf
      (setq ediff-window-A wind-A
	    ediff-window-B wind-B
	    ediff-window-C wind-C
            ediff-window-Ancestor wind-Ancestor)
      (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)
    ))