Function: diff-hunk-text
diff-hunk-text is a byte-compiled function defined in diff-mode.el.gz.
Signature
(diff-hunk-text HUNK DESTP CHAR-OFFSET)
Documentation
Return the literal source text from HUNK as (TEXT . OFFSET).
If DESTP is nil, TEXT is the source, otherwise the destination text. CHAR-OFFSET is a char-offset in HUNK, and OFFSET is the corresponding char-offset in TEXT.
Source Code
;; Defined in /usr/src/emacs/lisp/vc/diff-mode.el.gz
(defun diff-hunk-text (hunk destp char-offset)
"Return the literal source text from HUNK as (TEXT . OFFSET).
If DESTP is nil, TEXT is the source, otherwise the destination text.
CHAR-OFFSET is a char-offset in HUNK, and OFFSET is the corresponding
char-offset in TEXT."
(with-temp-buffer
(insert hunk)
(goto-char (point-min))
(let ((src-pos nil)
(dst-pos nil)
(divider-pos nil)
(num-pfx-chars 2))
;; Set the following variables:
;; SRC-POS buffer pos of the source part of the hunk or nil if none
;; DST-POS buffer pos of the destination part of the hunk or nil
;; DIVIDER-POS buffer pos of any divider line separating the src & dst
;; NUM-PFX-CHARS number of line-prefix characters used by this format"
(cond ((looking-at "^@@")
;; unified diff
(setq num-pfx-chars 1)
(forward-line 1)
(setq src-pos (point) dst-pos (point)))
((looking-at "^\\*\\*")
;; context diff
(forward-line 2)
(setq src-pos (point))
(re-search-forward diff-context-mid-hunk-header-re nil t)
(forward-line 0)
(setq divider-pos (point))
(forward-line 1)
(setq dst-pos (point)))
((looking-at "^[0-9]+a[0-9,]+$")
;; normal diff, insert
(forward-line 1)
(setq dst-pos (point)))
((looking-at "^[0-9,]+d[0-9]+$")
;; normal diff, delete
(forward-line 1)
(setq src-pos (point)))
((looking-at "^[0-9,]+c[0-9,]+$")
;; normal diff, change
(forward-line 1)
(setq src-pos (point))
(re-search-forward "^---$" nil t)
(forward-line 0)
(setq divider-pos (point))
(forward-line 1)
(setq dst-pos (point)))
(t
(error "Unknown diff hunk type")))
(if (if destp (null dst-pos) (null src-pos))
;; Implied empty text
(if char-offset '("" . 0) "")
;; For context diffs, either side can be empty, (if there's only
;; added or only removed text). We should then use the other side.
(cond ((equal src-pos divider-pos) (setq src-pos dst-pos))
((equal dst-pos (point-max)) (setq dst-pos src-pos)))
(when char-offset (goto-char (+ (point-min) char-offset)))
;; Get rid of anything except the desired text.
(save-excursion
;; Delete unused text region
(let ((keep (if destp dst-pos src-pos)))
(when (and divider-pos (> divider-pos keep))
(delete-region divider-pos (point-max)))
(delete-region (point-min) keep))
;; Remove line-prefix characters, and unneeded lines (unified diffs).
;; Also skip lines like "\ No newline at end of file"
(let ((kill-chars (list (if destp ?- ?+) ?\\))
curr-char last-char)
(goto-char (point-min))
(while (not (eobp))
(setq curr-char (char-after))
(if (memq curr-char kill-chars)
(delete-region
;; Check for "\ No newline at end of file"
(if (and (eq curr-char ?\\)
(not (eq last-char (if destp ?- ?+)))
(save-excursion
(forward-line 1)
(or (eobp) (and (eq last-char ?-)
(eq (char-after) ?+)))))
(max (1- (point)) (point-min))
(point))
(progn (forward-line 1) (point)))
(delete-char num-pfx-chars)
(forward-line 1))
(setq last-char curr-char))))
(let ((text (buffer-substring-no-properties (point-min) (point-max))))
(if char-offset (cons text (- (point) (point-min))) text))))))