Function: majutsu-conflict--parse-jj-hunk

majutsu-conflict--parse-jj-hunk is a natively compiled function defined in majutsu-conflict.el.

Signature

(majutsu-conflict--parse-jj-hunk BEGIN END MARKER-LEN)

Documentation

Parse JJ-style conflict hunk between BEGIN and END.

MARKER-LEN is the expected marker length. Returns (STYLE REMOVES ADDS BASE) or nil if invalid. BASE is the snapshot term shown as a standalone +++++++ section.

Source Code

;; Defined in /nix/store/jagqw3nms546pad0gxi5f3wsckk6pji7-emacs-packages-deps/share/emacs/site-lisp/majutsu-conflict.el
;;; JJ-Style Parser

(defun majutsu-conflict--parse-jj-hunk (begin end marker-len)
  "Parse JJ-style conflict hunk between BEGIN and END.
MARKER-LEN is the expected marker length.
Returns (STYLE REMOVES ADDS BASE) or nil if invalid.
BASE is the snapshot term shown as a standalone +++++++ section."
  (save-excursion
    (goto-char begin)
    (forward-line 1)  ; skip <<<<<<< line
    (let ((state 'unknown)
          (style 'jj-snapshot)
          (seen-diff nil)
          (removes nil)
          (adds nil)
          (current-remove nil)
          (current-add nil)
          (snapshot-cell nil)
          (done nil))
      (catch 'invalid
        (cl-labels
            ((append-cell (cell text)
               (setcdr cell (concat (cdr cell) text))))
          (while (and (not done) (< (point) end))
            (let* ((line (buffer-substring-no-properties
                          (line-beginning-position)
                          (line-end-position)))
                   (marker (majutsu-conflict--line-marker line marker-len))
                   (kind (car-safe marker))
                   (label (cdr-safe marker)))
              (pcase kind
                ('end
                 (setq done t))
                ('diff
                 (setq style 'jj-diff
                       seen-diff t
                       state 'diff)
                 (push (cons (majutsu-conflict--normalize-diff-remove-label label) "") removes)
                 (push (cons nil "") adds)
                 (setq current-remove (car removes)
                       current-add (car adds)))
                ('remove
                 (setq state 'remove)
                 (push (cons label "") removes)
                 (setq current-remove (car removes)))
                ('add
                 (setq state 'add)
                 (push (cons label "") adds)
                 (setq current-add (car adds))
                 (when (and (null snapshot-cell)
                            (or seen-diff
                                (and (null removes)
                                     (= (length adds) 1))))
                   (setq snapshot-cell current-add)))
                ('note
                 (when (and (eq state 'diff)
                            current-add
                            (null (car current-add)))
                   (setcar current-add
                           (majutsu-conflict--normalize-diff-add-label label))))
                (_
                 (pcase state
                   ('diff
                    (cond
                     ((string-prefix-p "-" line)
                      (append-cell current-remove (concat (substring line 1) "\n")))
                     ((string-prefix-p "+" line)
                      (append-cell current-add (concat (substring line 1) "\n")))
                     ((string-prefix-p " " line)
                      (let ((rest (concat (substring line 1) "\n")))
                        (append-cell current-remove rest)
                        (append-cell current-add rest)))
                     ((string= line "")
                      (append-cell current-remove "\n")
                      (append-cell current-add "\n"))
                     (t
                      (throw 'invalid nil))))
                   ('remove
                    (append-cell current-remove (concat line "\n")))
                   ('add
                    (append-cell current-add (concat line "\n")))
                   (_
                    (throw 'invalid nil))))))
            (unless done
              (forward-line 1))))
        (let* ((removes (nreverse removes))
               (all-adds (nreverse adds))
               (base nil)
               (side-adds nil))
          (dolist (cell all-adds)
            (if (eq cell snapshot-cell)
                (setq base cell)
              (push cell side-adds)))
          (setq side-adds (nreverse side-adds))
          (if (and base
                   (= (length side-adds) (length removes)))
              (list style removes side-adds base)
            nil))))))