Function: majutsu-interactive--build-hunk-patch
majutsu-interactive--build-hunk-patch is a natively compiled function
defined in majutsu-interactive.el.
Signature
(majutsu-interactive--build-hunk-patch SECTION SPEC &optional INVERT)
Documentation
Build a patch hunk for SECTION using SPEC and INVERT.
SPEC is :all or list of (BEG . END) ranges. When INVERT is non-nil, invert selection for change lines. Return a hunk string or nil when no change lines remain.
Source Code
;; Defined in /nix/store/jagqw3nms546pad0gxi5f3wsckk6pji7-emacs-packages-deps/share/emacs/site-lisp/majutsu-interactive.el
(defun majutsu-interactive--build-hunk-patch (section spec &optional invert)
"Build a patch hunk for SECTION using SPEC and INVERT.
SPEC is `:all' or list of (BEG . END) ranges.
When INVERT is non-nil, invert selection for change lines.
Return a hunk string or nil when no change lines remain."
(let* ((header (majutsu-interactive--hunk-header section))
(parsed (majutsu-interactive--parse-hunk-header header))
(lines (majutsu-interactive--group-hunk-lines
(majutsu-interactive--hunk-lines section)))
(ranges (cond
((eq spec :all) nil)
((consp spec) (if (and spec (consp (car spec))) spec (list spec)))
(t nil)))
(decided
(mapcar (lambda (line)
(pcase-let ((`(,text ,type ,bol ,eol ,meta) line))
(let ((selected (if ranges
(majutsu-interactive--line-selected-p
bol eol ranges)
t)))
(list text type meta
(if invert (not selected) selected)))))
lines))
(selected-lines nil)
(old-skip 0)
(new-skip 0)
(old-len 0)
(new-len 0)
(has-change nil)
(started nil)
(rest decided))
(while rest
(pcase-let ((`(,text ,type ,meta ,include-change) (car rest)))
(setq rest (cdr rest))
(if (not (pcase type
('context t)
('added include-change)
('removed t)))
(unless started
(pcase type
('added (setq new-skip (1+ new-skip)))
('removed (setq old-skip (1+ old-skip)))))
(setq started t)
(when (and (memq type '(added removed)) include-change)
(setq has-change t))
(cond
((and (eq type 'removed) (not include-change))
;; The line stays in both files. A plain context conversion
;; is wrong when it carries a no-newline marker and kept
;; added lines extend the new file past it: the new file
;; copy must gain a newline, so remove and re-add it.
(setq old-len (1+ old-len))
(setq new-len (1+ new-len))
(if (and meta
(seq-some (lambda (entry)
(and (eq (nth 1 entry) 'added)
(nth 3 entry)))
rest))
(progn
(push text selected-lines)
(push meta selected-lines)
(push (concat "+" (substring text 1)) selected-lines))
(push (concat " " (substring text 1)) selected-lines)
(when meta (push meta selected-lines))))
(t
(pcase type
('context (setq old-len (1+ old-len))
(setq new-len (1+ new-len)))
('removed (setq old-len (1+ old-len)))
('added (setq new-len (1+ new-len))))
(push text selected-lines)
(when meta (push meta selected-lines)))))))
(when (and has-change selected-lines)
(let* ((body (mapconcat #'identity (nreverse selected-lines) ""))
(hunk-header
(if parsed
(pcase-let ((`(,old-start ,_old-len ,new-start ,_new-len ,suffix) parsed))
(majutsu-interactive--format-hunk-header
(+ old-start old-skip)
old-len
(+ new-start new-skip)
new-len
suffix))
header)))
(concat hunk-header body)))))