Subject: enhancement request: hideshow should handle derived modes

From: Tobias Zawada <[email-masked]>
Date: Thu, 30 Jan 2020 10:24:35 +0100 (CET)

Hi,
hideshow.el should handle derived modes.
See discussion on emacs.SE about hideshow in sage-shell-mode (link: https://emacs.stackexchange.com/questions/55129/hs-minor-mode-and-sage-shell-mode-derived-from-python-mode#comment86297_55129).

I propose following change on `hs-grok-mode-type` (perma-link:
https://github.com/jwiegley/emacs-release/blob/adfd5933358fdf6715423dee8169eb3cd7d982db/lisp/progmodes/hideshow.el#L666):

@@ -7,7 +7,9 @@
   (if (and (boundp 'comment-start)
            (boundp 'comment-end)
            comment-start comment-end)
-      (let* ((lookup (assoc major-mode hs-special-modes-alist))
+      (let* ((lookup (cl-assoc-if (lambda (mode)
+				    (derived-mode-p major-mode mode))
+				  hs-special-modes-alist))
              (start-elem (or (nth 1 lookup) "\\s(")))
         (if (listp start-elem)
             ;; handle (START-REGEXP MDATA-SELECT)

The new version of `hs-grok-mode-type` in full would be:

(defun hs-grok-mode-type ()
  "Set up hideshow variables for new buffers.
If `hs-special-modes-alist' has information associated with the
current buffer's major mode, use that.
Otherwise, guess start, end and `comment-start' regexps; `forward-sexp'
function; and adjust-block-beginning function."
  (if (and (boundp 'comment-start)
           (boundp 'comment-end)
           comment-start comment-end)
      (let* ((lookup (cl-assoc-if (lambda (mode)
				    (derived-mode-p major-mode mode))
				  hs-special-modes-alist))
             (start-elem (or (nth 1 lookup) "\\s(")))
        (if (listp start-elem)
            ;; handle (START-REGEXP MDATA-SELECT)
            (setq hs-block-start-regexp (car start-elem)
                  hs-block-start-mdata-select (cadr start-elem))
          ;; backwards compatibility: handle simple START-REGEXP
          (setq hs-block-start-regexp start-elem
                hs-block-start-mdata-select 0))
        (setq hs-block-end-regexp (or (nth 2 lookup) "\\s)")
              hs-c-start-regexp (or (nth 3 lookup)
                                    (let ((c-start-regexp
                                           (regexp-quote comment-start)))
                                      (if (string-match " +$" c-start-regexp)
                                          (substring c-start-regexp
                                                     0 (1- (match-end 0)))
                                        c-start-regexp)))
              hs-forward-sexp-func (or (nth 4 lookup) 'forward-sexp)
              hs-adjust-block-beginning (nth 5 lookup)))
    (setq hs-minor-mode nil)
    (error "%s Mode doesn't support Hideshow Minor Mode"
           (format-mode-line mode-name))))

Best regards,
Tobias Zawada