Function: diff-wiggle

diff-wiggle is an interactive and byte-compiled function defined in diff-mode.el.gz.

Signature

(diff-wiggle)

Documentation

Use wiggle to apply the whole current file diff by hook or by crook.

When a hunk can't cleanly be applied, it gets turned into a diff3-style conflict.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/vc/diff-mode.el.gz
;;; Support for converting a diff to diff3 markers via `wiggle'.

;; Wiggle can be found at https://neil.brown.name/wiggle/ or in your nearest
;; Debian repository.

(defun diff-wiggle ()
  "Use `wiggle' to apply the whole current file diff by hook or by crook.
When a hunk can't cleanly be applied, it gets turned into a diff3-style
conflict."
  (interactive)
  (let* ((bounds (diff-bounds-of-file))
         (file (diff-find-file-name))
         (tmpbuf (current-buffer))
         (filebuf (find-buffer-visiting file))
         (patchfile (make-temp-file
                     (expand-file-name "wiggle" (file-name-directory file))
                     nil ".diff"))
         (errfile (make-temp-file
                     (expand-file-name "wiggle" (file-name-directory file))
                     nil ".error")))
    (unwind-protect
        (with-temp-buffer
          (set-buffer (prog1 tmpbuf (setq tmpbuf (current-buffer))))
          (when (buffer-modified-p filebuf)
            (save-some-buffers nil (lambda () (eq (current-buffer) filebuf)))
            (if (buffer-modified-p filebuf) (user-error "Abort!")))
          (write-region (car bounds) (cadr bounds) patchfile nil 'silent)
          (let ((exitcode
                 (call-process "wiggle" nil (list tmpbuf errfile) nil
                               file patchfile)))
            (if (not (memq exitcode '(0 1)))
                (message "diff-wiggle error: %s"
                         (with-current-buffer tmpbuf
                           (goto-char (point-min))
                           (insert-file-contents errfile)
                           (buffer-string)))
              (with-current-buffer tmpbuf
                (write-region nil nil file nil 'silent)
                (with-current-buffer filebuf
                  (revert-buffer t t t)
                  (save-excursion
                    (goto-char (point-min))
                    (if (re-search-forward "^<<<<<<<" nil t)
                        (smerge-mode 1)))
                  (pop-to-buffer filebuf))))))
      (delete-file patchfile)
      (delete-file errfile))))