Function: diff--revert-kill-hunks
diff--revert-kill-hunks is a byte-compiled function defined in
diff-mode.el.gz.
Signature
(diff--revert-kill-hunks BEG END REVERTP)
Documentation
Workhorse routine for killing hunks, after possibly reverting them.
If BEG and END are nil, kill the hunk at point. Otherwise kill all hunks overlapped by region delimited by BEG and END. When killing a hunk that's the only one remaining for its file, kill the file header too. If REVERTP is non-nil, reverse-apply hunks before killing them.
Source Code
;; Defined in /usr/src/emacs/lisp/vc/diff-mode.el.gz
(defun diff--revert-kill-hunks (beg end revertp)
"Workhorse routine for killing hunks, after possibly reverting them.
If BEG and END are nil, kill the hunk at point.
Otherwise kill all hunks overlapped by region delimited by BEG and END.
When killing a hunk that's the only one remaining for its file, kill the
file header too.
If REVERTP is non-nil, reverse-apply hunks before killing them."
;; With BEG and END non-nil, we push each hunk to the kill ring
;; separately. If we want to push to the kill ring just once, we have
;; to decide how to handle file headers such that the meanings of the
;; hunks in the kill ring entry, considered as a whole patch, do not
;; deviate too far from the meanings the hunks had in this buffer.
;;
;; For example, if we have a single hunk for one file followed by
;; multiple hunks for another file, and we naïvely kill the single
;; hunk and the first of the multiple hunks, our kill ring entry will
;; be a patch applying those two hunks to the first file. This is
;; because killing the single hunk will have brought its file header
;; with it, but not so killing the second hunk. So we will have put
;; together hunks that were previously for two different files.
;;
;; One option is to *copy* every file header that the region overlaps
;; (and that we will not kill, because we are leaving other hunks for
;; that file behind). But then the text this command pushes to the
;; kill ring would be different from the text it removes from the
;; buffer, which would be unintuitive for an Emacs kill command.
;;
;; An alternative might be to have restrictions as follows:
;;
;; Interactively, if the region is active, try to kill all hunks that the
;; region overlaps. This works when either
;; - all the hunks the region overlaps are for the same file; or
;; - the last hunk the region overlaps is the last hunk for its file.
;; These restrictions are so that the text added to the kill ring does not
;; merge together hunks for different files under a single file header.
;;
;; We would error out if neither property is met. When either holds,
;; any file headers the region overlaps are ones we should kill.
(unless (diff--some-hunks-p)
(error "No hunks"))
(if beg
(save-excursion
(goto-char beg)
(setq beg (car (diff-bounds-of-hunk)))
(goto-char end)
(unless (looking-at diff-hunk-header-re)
(setq end (cadr (diff-bounds-of-hunk)))))
(pcase-setq `(,beg ,end) (diff-bounds-of-hunk)))
(when (or (not revertp) (null (diff-apply-buffer beg end t)))
(goto-char end)
(when-let* ((pos (diff--at-diff-header-p)))
(goto-char pos))
(setq beg (copy-marker beg) end (point-marker))
(unwind-protect
(cl-loop initially (goto-char beg)
with inhibit-read-only = t
for (hunk-beg hunk-end) = (diff-bounds-of-hunk)
for file-bounds = (ignore-errors (diff-bounds-of-file))
for (file-beg file-end) = file-bounds
if (and file-bounds
(progn
(goto-char file-beg)
(diff-hunk-next)
(eq (point) hunk-beg))
(progn
(goto-char hunk-end)
;; bzr puts a newline after the last hunk.
(while (looking-at "^\n") (forward-char 1))
(eq (point) file-end)))
do (kill-region file-beg file-end) (goto-char file-beg)
else do (kill-region hunk-beg hunk-end) (goto-char hunk-beg)
do (ignore-errors (diff-beginning-of-hunk t))
until (or (< (point) (marker-position beg))
(eql (point) (marker-position end))))
(set-marker beg nil)
(set-marker end nil))))