Subject: Re: bug#53981: 28.0.91; shortdoc: Add support for outline-minor-mode

From: Juri Linkov <[email-masked]>
Date: Wed, 16 Feb 2022 20:18:35 +0200

> As previously discussed in some other bug report *vague hand wave*, it
> makes no sense to use regexps for outline in generated buffers.  The
> functions that generate the buffers knows what's a heading, and should
> mark the headings properly (with text properties), and
> outline-minor-mode should just react to these text properties in these
> buffers.

That was in https://debbugs.gnu.org/31094#40

Is this a promising direction?

diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index 658edd6752..63e799a2be 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -1435,7 +1435,19 @@ shortdoc-mode-map
 
 (define-derived-mode shortdoc-mode special-mode "shortdoc"
   "Mode for shortdoc."
-  :interactive nil)
+  :interactive nil
+  (setq-local outline-level (lambda () (if (eq (char-after) ?\() 2 1)))
+  (setq-local outline-search-function
+              (lambda (&optional looking-at)
+                (save-excursion
+                  (let* ((prop-at (if looking-at
+                                      (get-text-property (point) 'shortdoc-section)
+                                    t))
+                         (prop-match (and prop-at (text-property-search-forward 'shortdoc-section))))
+                    (when prop-match
+                      (set-match-data (list (prop-match-beginning prop-match)
+                                            (prop-match-end prop-match)))
+                      t))))))
 
 (defun shortdoc--goto-section (arg sym &optional reverse)
   (unless (natnump arg)
diff --git a/lisp/outline.el b/lisp/outline.el
index 012e219fc3..a282237696 100644
--- a/lisp/outline.el
+++ b/lisp/outline.el
@@ -301,7 +303,9 @@ outline-font-lock-face
   "Return one of `outline-font-lock-faces' for current level."
   (save-excursion
     (goto-char (match-beginning 0))
-    (looking-at outline-regexp)
+    (if outline-search-function
+        (funcall outline-search-function t)
+      (looking-at outline-regexp))
     (aref outline-font-lock-faces
           (% (1- (funcall outline-level))
              (length outline-font-lock-faces)))))
@@ -393,14 +397,19 @@ outline-minor-mode-highlight
   :safe #'symbolp
   :version "28.1")
 
+(defvar outline-search-function nil
+  "Function to search the next outline.
+It should be like `re-search-forward' and `looking-at'.")
+
 (defun outline-minor-mode-highlight-buffer ()
   ;; Fallback to overlays when font-lock is unsupported.
   (save-excursion
     (goto-char (point-min))
     (let ((regexp (concat "^\\(?:" outline-regexp "\\).*$")))
-      (while (re-search-forward regexp nil t)
-        (let ((overlay (make-overlay (match-beginning 0)
-                                     (match-end 0))))
+      (while (if outline-search-function
+                 (funcall outline-search-function)
+               (re-search-forward regexp nil t))
+        (let ((overlay (make-overlay (match-beginning 0) (match-end 0))))
           (overlay-put overlay 'outline-overlay t)
           (when (or (eq outline-minor-mode-highlight 'override)
                     (and (eq outline-minor-mode-highlight t)
@@ -535,7 +544,9 @@ outline-on-heading-p
   (save-excursion
     (beginning-of-line)
     (and (bolp) (or invisible-ok (not (outline-invisible-p)))
-	 (looking-at outline-regexp))))
+	 (if outline-search-function
+             (funcall outline-search-function t)
+           (looking-at outline-regexp)))))
 
 (defun outline-insert-heading ()
   "Insert a new heading at same depth at point."