Function: ediff-setup
ediff-setup is a byte-compiled function defined in ediff-util.el.gz.
Signature
(ediff-setup BUFFER-A FILE-A BUFFER-B FILE-B BUFFER-C FILE-C STARTUP-HOOKS SETUP-PARAMETERS &optional MERGE-BUFFER-FILE)
Source Code
;; Defined in /usr/src/emacs/lisp/vc/ediff-util.el.gz
;;; Setup functions
;; Common startup entry for all Ediff functions It now returns control buffer
;; so other functions can do post-processing SETUP-PARAMETERS is a list of the
;; form ((param .val) (param . val)...) This serves a similar purpose to
;; STARTUP-HOOKS, but these parameters are set in the new control buffer right
;; after this buf is created and before any windows are set and such.
(defun ediff-setup (buffer-A file-A buffer-B file-B buffer-C file-C
startup-hooks setup-parameters
&optional merge-buffer-file)
(run-hooks 'ediff-before-setup-hook)
;; convert-standard-filename puts file names in the form appropriate
;; for the OS at hand.
(setq file-A (convert-standard-filename (expand-file-name file-A)))
(setq file-B (convert-standard-filename (expand-file-name file-B)))
(if (stringp file-C)
(setq file-C (convert-standard-filename (expand-file-name file-C))))
(if (stringp merge-buffer-file)
(progn
(setq merge-buffer-file
(convert-standard-filename (expand-file-name merge-buffer-file)))
;; check the directory exists
(or (file-exists-p (file-name-directory merge-buffer-file))
(error "Directory %s given as place to save the merge doesn't exist"
(abbreviate-file-name
(file-name-directory merge-buffer-file))))
(if (and (file-exists-p merge-buffer-file)
(file-directory-p merge-buffer-file))
(error "The merge buffer file %s must not be a directory"
(abbreviate-file-name merge-buffer-file)))
))
(let* ((control-buffer-name
(ediff-unique-buffer-name "*Ediff Control Panel" "*"))
(control-buffer (ediff-with-current-buffer buffer-A
(get-buffer-create control-buffer-name))))
(ediff-with-current-buffer control-buffer
(ediff-mode)
(make-local-variable 'ediff-use-long-help-message)
(make-local-variable 'ediff-prefer-iconified-control-frame)
(make-local-variable 'ediff-split-window-function)
(make-local-variable 'ediff-default-variant)
(make-local-variable 'ediff-merge-window-share)
(make-local-variable 'ediff-window-setup-function)
(make-local-variable 'ediff-keep-variants)
(setq-local window-min-height 2)
;; unwrap set up parameters passed as argument
(while setup-parameters
(set (car (car setup-parameters)) (cdr (car setup-parameters)))
(setq setup-parameters (cdr setup-parameters)))
;; set variables classifying the current ediff job
;; must come AFTER setup-parameters
(setq ediff-3way-comparison-job (ediff-3way-comparison-job)
ediff-merge-job (ediff-merge-job)
ediff-merge-with-ancestor-job (ediff-merge-with-ancestor-job)
ediff-3way-job (ediff-3way-job)
ediff-diff3-job (ediff-diff3-job)
ediff-narrow-job (ediff-narrow-job)
ediff-windows-job (ediff-windows-job)
ediff-word-mode-job (ediff-word-mode-job))
;; Don't delete variants in case of ediff-buffer-* jobs without asking.
;; This is because one may lose work---dangerous.
(if (string-match "buffer" (symbol-name ediff-job-name))
(setq ediff-keep-variants t))
;; adjust for merge jobs
(if ediff-merge-job
(let ((buf
;; If default variant is `combined', the right stuff is
;; inserted by ediff-do-merge
;; Note: at some point, we tried to put ancestor buffer here
;; (which is currently buffer C. This didn't work right
;; because the merge buffer will contain lossage: diff regions
;; in the ancestor, which correspond to revisions that agree
;; in both buf A and B.
(cond ((eq ediff-default-variant 'default-B)
buffer-B)
(t buffer-A))))
(setq ediff-split-window-function
ediff-merge-split-window-function)
;; remember the ancestor buffer, if any
(setq ediff-ancestor-buffer buffer-C)
(setq buffer-C
(get-buffer-create
(ediff-unique-buffer-name "*ediff-merge" "*")))
(with-current-buffer buffer-C
(insert-buffer-substring buf)
(goto-char (point-min))
(funcall (ediff-with-current-buffer buf major-mode))
(widen) ; merge buffer is always widened
(add-hook 'write-file-functions 'ediff-set-merge-mode nil t)
)))
(setq buffer-read-only nil
ediff-buffer-A buffer-A
ediff-buffer-B buffer-B
ediff-buffer-C buffer-C
ediff-control-buffer control-buffer)
(ediff-choose-syntax-table)
(setq ediff-control-buffer-suffix
(if (string-match "<[0-9]*>" control-buffer-name)
(substring control-buffer-name
(match-beginning 0) (match-end 0))
"")
ediff-control-buffer-number
(max
0
(1-
(string-to-number
(substring
ediff-control-buffer-suffix
(or
(string-match "[0-9]+" ediff-control-buffer-suffix)
0))))))
(setq ediff-error-buffer
(get-buffer-create (ediff-unique-buffer-name "*ediff-errors" "*")))
(with-current-buffer ediff-error-buffer
(setq buffer-undo-list t))
(ediff-with-current-buffer buffer-A (ediff-strip-mode-line-format))
(ediff-with-current-buffer buffer-B (ediff-strip-mode-line-format))
(if ediff-3way-job
(ediff-with-current-buffer buffer-C (ediff-strip-mode-line-format)))
(if (ediff-buffer-live-p ediff-ancestor-buffer)
(ediff-with-current-buffer ediff-ancestor-buffer
(ediff-strip-mode-line-format)))
(ediff-save-protected-variables) ; save variables to be restored on exit
;; ediff-setup-diff-regions-function must be set after setup
;; parameters are processed.
(setq ediff-setup-diff-regions-function
(if ediff-diff3-job
#'ediff-setup-diff-regions3
#'ediff-setup-diff-regions))
(setq ediff-wide-bounds
(list (ediff-make-bullet-proof-overlay
'(point-min) '(point-max) ediff-buffer-A)
(ediff-make-bullet-proof-overlay
'(point-min) '(point-max) ediff-buffer-B)
(ediff-make-bullet-proof-overlay
'(point-min) '(point-max) ediff-buffer-C)))
;; This has effect only on ediff-windows/regions
;; In all other cases, ediff-visible-region sets visibility bounds to
;; ediff-wide-bounds, and ediff-narrow-bounds are ignored.
(if ediff-start-narrowed
(setq ediff-visible-bounds ediff-narrow-bounds)
(setq ediff-visible-bounds ediff-wide-bounds))
(ediff-set-keys) ; comes after parameter setup
;; set up ediff-narrow-bounds, if not set
(or ediff-narrow-bounds
(setq ediff-narrow-bounds ediff-wide-bounds))
;; All these must be inside ediff-with-current-buffer control-buffer,
;; since these vars are local to control-buffer
;; These won't run if there are errors in diff
(ediff-with-current-buffer ediff-buffer-A
(run-hooks 'ediff-prepare-buffer-hook)
(if (ediff-with-current-buffer control-buffer ediff-merge-job)
(setq buffer-read-only t))
;; add control-buffer to the list of sessions--no longer used, but may
;; be used again in the future
(or (memq control-buffer ediff-this-buffer-ediff-sessions)
(setq ediff-this-buffer-ediff-sessions
(cons control-buffer ediff-this-buffer-ediff-sessions)))
(if ediff-make-buffers-readonly-at-startup
(setq buffer-read-only t))
)
(ediff-with-current-buffer ediff-buffer-B
(run-hooks 'ediff-prepare-buffer-hook)
(if (ediff-with-current-buffer control-buffer ediff-merge-job)
(setq buffer-read-only t))
;; add control-buffer to the list of sessions
(or (memq control-buffer ediff-this-buffer-ediff-sessions)
(setq ediff-this-buffer-ediff-sessions
(cons control-buffer ediff-this-buffer-ediff-sessions)))
(if ediff-make-buffers-readonly-at-startup
(setq buffer-read-only t))
)
(if ediff-3way-job
(ediff-with-current-buffer ediff-buffer-C
;; the merge buffer should never be narrowed
;; (it can happen if it is on rmail-mode or similar)
(if (ediff-with-current-buffer control-buffer ediff-merge-job)
(widen))
(run-hooks 'ediff-prepare-buffer-hook)
;; add control-buffer to the list of sessions
(or (memq control-buffer ediff-this-buffer-ediff-sessions)
(setq ediff-this-buffer-ediff-sessions
(cons control-buffer
ediff-this-buffer-ediff-sessions)))
(if ediff-make-buffers-readonly-at-startup
(setq buffer-read-only t)
(setq buffer-read-only nil))
))
(if (ediff-buffer-live-p ediff-ancestor-buffer)
(ediff-with-current-buffer ediff-ancestor-buffer
(setq buffer-read-only t)
(run-hooks 'ediff-prepare-buffer-hook)
(or (memq control-buffer ediff-this-buffer-ediff-sessions)
(setq ediff-this-buffer-ediff-sessions
(cons control-buffer
ediff-this-buffer-ediff-sessions)))
))
;; the following must be after setting up ediff-narrow-bounds AND after
;; nuking selective display
(funcall ediff-setup-diff-regions-function file-A file-B file-C)
(setq ediff-number-of-differences (length ediff-difference-vector-A))
(setq ediff-current-difference -1)
(ediff-make-current-diff-overlay 'A)
(ediff-make-current-diff-overlay 'B)
(if ediff-3way-job
(ediff-make-current-diff-overlay 'C))
(if ediff-merge-with-ancestor-job
(ediff-make-current-diff-overlay 'Ancestor))
(ediff-setup-windows buffer-A buffer-B buffer-C control-buffer)
(let ((shift-A (ediff-overlay-start
(ediff-get-value-according-to-buffer-type
'A ediff-narrow-bounds)))
(shift-B (ediff-overlay-start
(ediff-get-value-according-to-buffer-type
'B ediff-narrow-bounds)))
(shift-C (ediff-overlay-start
(ediff-get-value-according-to-buffer-type
'C ediff-narrow-bounds))))
;; position point in buf A
(when (window-live-p ediff-window-A)
(with-selected-window ediff-window-A
(goto-char shift-A)))
;; position point in buf B
(when (window-live-p ediff-window-B)
(with-selected-window ediff-window-B
(goto-char shift-B)))
(if (and ediff-3way-job (window-live-p ediff-window-C))
(with-selected-window ediff-window-C
(goto-char shift-C))))
(when (and ediff-select-control-window-on-setup
(window-live-p ediff-control-window))
(select-window ediff-control-window))
(ediff-visible-region)
(mapc #'funcall startup-hooks)
(ediff-arrange-autosave-in-merge-jobs merge-buffer-file)
(ediff-refresh-mode-lines)
(setq buffer-read-only t)
(setq ediff-session-registry
(cons control-buffer ediff-session-registry))
(ediff-update-registry)
(if (ediff-buffer-live-p ediff-meta-buffer)
(ediff-update-meta-buffer
ediff-meta-buffer nil ediff-meta-session-number))
(add-hook 'kill-emacs-hook #'ediff--delete-temp-files-on-kill-emacs)
(run-hooks 'ediff-startup-hook)
) ; eval in control-buffer
control-buffer))