Function: smerge-ediff

smerge-ediff is an autoloaded, interactive and byte-compiled function defined in smerge-mode.el.gz.

Signature

(smerge-ediff &optional NAME-UPPER NAME-LOWER NAME-BASE)

Documentation

Invoke ediff to resolve the conflicts.

NAME-UPPER, NAME-LOWER, and NAME-BASE, if non-nil, are used for the buffer names.

Key Bindings

Aliases

vc-resolve-conflicts

Source Code

;; Defined in /usr/src/emacs/lisp/vc/smerge-mode.el.gz
;;;###autoload
(defun smerge-ediff (&optional name-upper name-lower name-base)
  "Invoke ediff to resolve the conflicts.
NAME-UPPER, NAME-LOWER, and NAME-BASE, if non-nil, are used for the
buffer names."
  (interactive)
  (let* ((buf (current-buffer))
	 (mode major-mode)
	 ;;(ediff-default-variant 'default-B)
	 (config (current-window-configuration))
	 (filename (file-name-nondirectory (or buffer-file-name "-")))
	 (upper (generate-new-buffer
		(or name-upper
                    (concat "*" filename " "
                            (smerge--get-marker smerge-begin-re "UPPER")
                            "*"))))
	 (lower (generate-new-buffer
		 (or name-lower
                     (concat "*" filename " "
                             (smerge--get-marker smerge-end-re "LOWER")
                             "*"))))
	 base)
    (with-current-buffer upper
      (buffer-disable-undo)
      (insert-buffer-substring buf)
      (goto-char (point-min))
      (while (smerge-find-conflict)
	(when (match-beginning 2) (setq base t))
	(smerge-keep-n 1))
      (buffer-enable-undo)
      (set-buffer-modified-p nil)
      (funcall mode))

    (with-current-buffer lower
      (buffer-disable-undo)
      (insert-buffer-substring buf)
      (goto-char (point-min))
      (while (smerge-find-conflict)
	(smerge-keep-n 3))
      (buffer-enable-undo)
      (set-buffer-modified-p nil)
      (funcall mode))

    (when base
      (setq base (generate-new-buffer
		  (or name-base
                      (concat "*" filename " "
                              (smerge--get-marker smerge-base-re "BASE")
                              "*"))))
      (with-current-buffer base
	(buffer-disable-undo)
	(insert-buffer-substring buf)
	(goto-char (point-min))
	(while (smerge-find-conflict)
	  (if (match-end 2)
	      (smerge-keep-n 2)
	    (delete-region (match-beginning 0) (match-end 0))))
	(buffer-enable-undo)
	(set-buffer-modified-p nil)
	(funcall mode)))

    ;; the rest of the code is inspired from vc.el
    ;; Fire up ediff.
    (set-buffer
     (if base
	 (ediff-merge-buffers-with-ancestor upper lower base)
	  ;; nil 'ediff-merge-revisions-with-ancestor buffer-file-name)
       (ediff-merge-buffers upper lower)))
        ;; nil 'ediff-merge-revisions buffer-file-name)))

    ;; Ediff is now set up, and we are in the control buffer.
    ;; Do a few further adjustments and take precautions for exit.
    (setq-local smerge-ediff-windows config)
    (setq-local smerge-ediff-buf buf)
    (add-hook 'ediff-quit-hook
	      (lambda ()
		(let ((buffer-A ediff-buffer-A)
		      (buffer-B ediff-buffer-B)
		      (buffer-C ediff-buffer-C)
		      (buffer-Ancestor ediff-ancestor-buffer)
		      (buf smerge-ediff-buf)
		      (windows smerge-ediff-windows))
		  (ediff-cleanup-mess)
		  (with-current-buffer buf
		    (erase-buffer)
		    (insert-buffer-substring buffer-C)
		    (kill-buffer buffer-A)
		    (kill-buffer buffer-B)
		    (kill-buffer buffer-C)
		    (when (bufferp buffer-Ancestor)
		      (kill-buffer buffer-Ancestor))
		    (set-window-configuration windows)
		    (message "Conflict resolution finished; you may save the buffer"))))
	      nil t)
    (message "Please resolve conflicts now; exit ediff when done")))