Function: eca-diff-show-smerge

eca-diff-show-smerge is a natively compiled function defined in eca-diff.el.

Signature

(eca-diff-show-smerge PATH DIFF &optional CHAT-BUF REDISPLAY-FN _)

Documentation

Show DIFF for file at PATH using Smerge in a dedicated window.

If CHAT-BUF is provided, REDISPLAY-FN (called with CHAT-BUF) will be used to re-show the chat window when the smerge buffer is killed.

Source Code

;; Defined in /nix/store/jklqzw6pzz6j4jrbv8wy0iwgi7jlrbld-emacs-packages-deps/share/emacs/site-lisp/elpa/eca-20260928.1827/eca-diff.el
(defun eca-diff-show-smerge (path diff &optional chat-buf redisplay-fn _)
  "Show DIFF for file at PATH using Smerge in a dedicated window.
If CHAT-BUF is provided, REDISPLAY-FN (called with CHAT-BUF) will be used
to re-show the chat window when the smerge buffer is killed."
  (let* ((parsed (eca-diff-parse-unified-diff diff))
         (orig   (plist-get parsed :original))
         (new    (plist-get parsed :new))
         (buf    (generate-new-buffer (format "*eca-smerge:%s*" path)))
         (cwc    (current-window-configuration))
         (orig-selected (selected-window))
         (frame  (selected-frame))
         (cleanup-running nil)
         cleanup-fn
         window-config-hook
         (redisplay-fn (or redisplay-fn #'eca-diff--default-redisplay-fn)))

    ;; Fill buffer with conflict markers
    (with-current-buffer buf
      (let ((inhibit-read-only t))
        (erase-buffer)
        (insert (concat "<<<<<<< Original\n" orig "\n=======\n" new "\n>>>>>>> New\n"))
        (diff-mode)
        (smerge-mode 1)
        (goto-char (point-min))))

    ;; Define cleanup that restores window configuration and kills the buffer
    (setq cleanup-fn
          (lambda ()
            (unless cleanup-running
              (setq cleanup-running t)
              (when (window-configuration-p cwc)
                (ignore-errors (set-window-configuration cwc)))
              (when (window-live-p orig-selected)
                (select-window orig-selected))
              (when (buffer-live-p buf)
                (with-current-buffer buf
                  (remove-hook 'kill-buffer-hook cleanup-fn t)))
              (when (functionp window-config-hook)
                (remove-hook 'window-configuration-change-hook window-config-hook))
              (when (buffer-live-p buf)
                (kill-buffer buf))
              ;; Re-display chat buffer if needed
              (when (and (buffer-live-p chat-buf)
                         (or (not (get-buffer-window chat-buf t))
                             (not (window-parameter (get-buffer-window chat-buf t) 'window-side))))
                (ignore-errors (funcall redisplay-fn chat-buf))))))

    ;; If buffer is no longer visible, run cleanup
    (setq window-config-hook
          (lambda ()
            (unless (get-buffer-window buf t)
              (funcall cleanup-fn))))
    (add-hook 'window-configuration-change-hook window-config-hook)

    ;; Add local keymap and kill hook to the smerge buffer
    (with-current-buffer buf
      (let ((map (make-sparse-keymap)))
        (set-keymap-parent map (current-local-map))
        (define-key map (kbd "q") (lambda () (interactive) (funcall cleanup-fn)))
        (use-local-map map))
      (add-hook 'kill-buffer-hook cleanup-fn nil t))

    ;; Temporarily relax side-window protections in the current frame so
    ;; `delete-other-windows' can succeed. The original window
    ;; configuration is restored by `cleanup-fn' (which calls `set-window-configuration').
    (dolist (w (seq-filter (lambda (w)
                             (and (eq (window-frame w) frame)
                                  (or (window-parameter w 'no-delete-other-windows)
                                      (window-parameter w 'window-side))))
                           (window-list)))
      (when (window-live-p w)
        (set-window-parameter w 'no-delete-other-windows nil)
        (set-window-parameter w 'window-side nil)))
    ;; Present the buffer full-frame
    (when (window-live-p (frame-root-window frame))
      (select-window (frame-root-window frame)))
    (unless (one-window-p t)
      (delete-other-windows))
    (switch-to-buffer buf)

    ;; Return nil explicitly
    nil))