Function: diff-add-log-current-defuns
diff-add-log-current-defuns is a byte-compiled function defined in
diff-mode.el.gz.
Signature
(diff-add-log-current-defuns)
Documentation
Return an alist of defun names for the current diff.
The elements of the alist are of the form (FILE . (DEFUN...)),
where DEFUN... is a list of function names found in FILE. If
diff-add-log-use-relative-names is non-nil, file names in the alist
are relative to the root directory of the VC repository.
Source Code
;; Defined in /usr/src/emacs/lisp/vc/diff-mode.el.gz
(defun diff-add-log-current-defuns ()
"Return an alist of defun names for the current diff.
The elements of the alist are of the form (FILE . (DEFUN...)),
where DEFUN... is a list of function names found in FILE. If
`diff-add-log-use-relative-names' is non-nil, file names in the alist
are relative to the root directory of the VC repository."
(save-excursion
(goto-char (point-min))
(let* ((defuns nil)
(hunk-end nil)
(hunk-mismatch-files nil)
(make-defun-context-follower
(lambda (goline)
(let ((eodefun nil)
(defname nil))
(list
(lambda () ;; Check for end of current defun.
(when (and eodefun
(funcall goline)
(>= (point) eodefun))
(setq defname nil)
(setq eodefun nil)))
(lambda (&optional get-current) ;; Check for new defun.
(if get-current
defname
(when-let* ((def (and (not eodefun)
(funcall goline)
(add-log-current-defun)))
(eof (save-excursion
(condition-case ()
(progn (end-of-defun) (point))
(scan-error hunk-end)))))
(setq eodefun eof)
(setq defname def)))))))))
(while
;; Might need to skip over file headers between diff
;; hunks (e.g., "diff --git ..." etc).
(re-search-forward diff-hunk-header-re nil t)
(setq hunk-end (save-excursion (diff-end-of-hunk)))
(pcase-let* ((filename (substring-no-properties
(if diff-add-log-use-relative-names
(file-relative-name
(diff-find-file-name)
(vc-root-dir))
(diff-find-file-name))))
(=lines 0)
(+lines 0)
(-lines 0)
(`(,buf ,line-offset (,beg . ,_end)
(,old-text . ,_old-offset)
(,new-text . ,_new-offset)
,applied)
;; Try to use the vc integration of
;; `diff-find-source-location', unless it
;; would look for non-existent files like
;; /dev/null.
(diff-find-source-location
(not (equal null-device
(car (diff-hunk-file-names t))))))
(other-buf nil)
(goto-otherbuf
;; If APPLIED, we have NEW-TEXT in BUF, so we
;; need to a buffer with OLD-TEXT to follow
;; -lines.
(lambda ()
(if other-buf (set-buffer other-buf)
(set-buffer (generate-new-buffer " *diff-other-text*"))
(insert (if applied old-text new-text))
(let ((delay-mode-hooks t))
(funcall (buffer-local-value 'major-mode buf)))
(setq other-buf (current-buffer)))
(goto-char (point-min))
(forward-line (+ =lines -1
(if applied -lines +lines)))))
(gotobuf (lambda ()
(set-buffer buf)
(goto-char beg)
(forward-line (+ =lines -1
(if applied +lines -lines)))))
(`(,=ck-eodefun ,=ck-defun)
(funcall make-defun-context-follower gotobuf))
(`(,-ck-eodefun ,-ck-defun)
(funcall make-defun-context-follower
(if applied goto-otherbuf gotobuf)))
(`(,+ck-eodefun ,+ck-defun)
(funcall make-defun-context-follower
(if applied gotobuf goto-otherbuf))))
(unless (eql line-offset 0)
(cl-pushnew filename hunk-mismatch-files :test #'equal))
;; Some modes always return nil for `add-log-current-defun',
;; make sure at least the filename is included.
(unless (assoc filename defuns)
(push (cons filename nil) defuns))
(unwind-protect
(while (progn (forward-line)
(< (point) hunk-end))
(let ((patch-char (char-after)))
(pcase patch-char
(?+ (incf +lines))
(?- (incf -lines))
(?\s (incf =lines)))
(save-current-buffer
(funcall =ck-eodefun)
(funcall +ck-eodefun)
(funcall -ck-eodefun)
(when-let* ((def (cond
((eq patch-char ?\s)
;; Just updating context defun.
(ignore (funcall =ck-defun)))
;; + or - in existing defun.
((funcall =ck-defun t))
;; Check added or removed defun.
(t (funcall (if (eq ?+ patch-char)
+ck-defun -ck-defun))))))
(cl-pushnew def (alist-get filename defuns
nil nil #'equal)
:test #'equal)))))
(when (buffer-live-p other-buf)
(kill-buffer other-buf)))))
(when hunk-mismatch-files
(message "Diff didn't match for %s."
(mapconcat #'identity hunk-mismatch-files ", ")))
(dolist (file-defuns defuns)
(cl-callf nreverse (cdr file-defuns)))
(nreverse defuns))))