Subject: diff-outline-regexp

From: Juri Linkov <[email-masked]>
Date: Mon, 05 May 2025 22:10:25 +0300

I noticed that 'diff-setup-buffer-type' overrides the default value
of 'diff-outline-regexp'.  Here is the fix:

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index a5f4169a7f3..76703526b63 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -1719,7 +1719,7 @@ diff-setup-buffer-type
                       'hg
                     nil))))
   (when (eq diff-buffer-type 'git)
-    (setq diff-outline-regexp
+    (setq-local diff-outline-regexp
           (concat "\\(^diff --git.*\\|" diff-hunk-header-re "\\)")))
   (setq-local outline-level #'diff--outline-level)
   (setq-local outline-regexp diff-outline-regexp))

Probably no one noticed this problem because its current default value
is not useful to anyone:

  (defvar diff-outline-regexp
    "\\([*+][*+][*+] [^0-9]\\|@@ ...\\|\\*\\*\\* [0-9].\\|--- [0-9]..\\)")

Maybe the default should be replaced with something like

  (defvar diff-outline-regexp
    (concat "\\(^diff -.*\\|" diff-hunk-header-re "\\)"))

that is useful for file-based diff.  Or maybe the value for file-based diff
should be set in 'diff-no-select' like this?

diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el
index c8a1b7c0efa..62c4ba6d302 100644
--- a/lisp/vc/diff.el
+++ b/lisp/vc/diff.el
@@ -196,6 +196,9 @@ diff-no-select
 	(erase-buffer))
       (buffer-enable-undo (current-buffer))
       (diff-mode)
+      (setq-local diff-outline-regexp
+                  (concat "\\(^" diff-command ".*\\|" diff-hunk-header-re "\\)")
+                  outline-regexp diff-outline-regexp)
       (setq-local revert-buffer-function
                   (lambda (_ignore-auto _noconfirm)
                     (diff-no-select old new switches no-async (current-buffer))))

But I might be missing more use cases.