GNU bug report logs - #79671
(WIP) [PATCH] hideshow: Rewrite 'hs-special-modes-alist'

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: emacs; Reported by: Elijah Gabe Pérez <eg642616@HIDDEN>; Keywords: patch; Done: Juri Linkov <juri@HIDDEN>; Maintainer for emacs is bug-gnu-emacs@HIDDEN.
bug marked as fixed in version 31.0.50, send any further explanations to 79671 <at> debbugs.gnu.org and Elijah Gabe Pérez <eg642616@HIDDEN> Request was from Juri Linkov <juri@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 4 Nov 2025 17:17:25 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Nov 04 12:17:25 2025
Received: from localhost ([127.0.0.1]:48656 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vGKeq-0001J3-Qm
	for submit <at> debbugs.gnu.org; Tue, 04 Nov 2025 12:17:25 -0500
Received: from mout-p-103.mailbox.org ([80.241.56.161]:47234)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>)
 id 1vGKef-0001Hj-OS; Tue, 04 Nov 2025 12:17:15 -0500
Received: from smtp202.mailbox.org (smtp202.mailbox.org [10.196.197.202])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by mout-p-103.mailbox.org (Postfix) with ESMTPS id 4d1FW56WXsz9tjW;
 Tue,  4 Nov 2025 18:17:05 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1762276625;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
 in-reply-to:in-reply-to:references:references;
 bh=pfdhDAuPDoiCovUBdqOwVh8FI/qLtafbMupz+6q0KQQ=;
 b=Uu1xzCtbdhAg9B3rtTIrf3yAo1NxpqzTgs3Q+A/tlMe1GCFuk1ypDvt1d0alPETm/vST4E
 35EfDt74/lp+KHlbdTvMX1H/2cffvHmw/CK7VhpGCTiHcYycHzWprHF7mbQZiH+zN05Fbh
 gWS8BJFxr0KthmQQwedJAnMBLCDPOriGe7L8abHwYju/NGRZYgYz5YP9MZLXzWveiOPeIm
 SnYIARV5/Z5fLLN8hFsOEUXh4NhPxhqGPz/Ug3g+WQqw76Ea/FS6rBBugEPN62dne0GD5o
 cz/UiO5Y1oPrM3GM8Y7dWNUaph/OPbFwL1+qaLCEHlr/iaJsUPjyfdco00McIw==
From: Juri Linkov <juri@HIDDEN>
To: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <87cy62dcic.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN> <87frb0qsng.fsf@HIDDEN>
 <87ecqk73sh.fsf@HIDDEN> <875xbw5i7q.fsf@HIDDEN>
 <874irgrxwq.fsf@HIDDEN> <87wm4bbjk1.fsf@HIDDEN>
 <87cy62dcic.fsf@HIDDEN>
Date: Tue, 04 Nov 2025 19:15:51 +0200
Message-ID: <87v7jp3eig.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>, Eli Zaretskii <eliz@HIDDEN>,
 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

close 79671 31.0.50
thanks

> Fine, i've updated the patch, it should not override the variables that
> are important for treesit, some variables such as
> `hs-adjust-block-beginning` defaulted to `identity` before, and changing
> it to nil will break hideshow.
>
> Also i added a new value as replacement for `hs-inside-comment-p`, which
> was redundant.

Thanks, now your patch is pushed.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 31 Oct 2025 20:48:00 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Oct 31 16:47:59 2025
Received: from localhost ([127.0.0.1]:44873 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vEw2P-0004gv-TI
	for submit <at> debbugs.gnu.org; Fri, 31 Oct 2025 16:47:59 -0400
Received: from mail-yx1-xb143.google.com ([2607:f8b0:4864:20::b143]:55805)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vEw2H-0004gd-R1
 for 79671 <at> debbugs.gnu.org; Fri, 31 Oct 2025 16:47:52 -0400
Received: by mail-yx1-xb143.google.com with SMTP id
 956f58d0204a3-63bc1aeb427so2994287d50.3
 for <79671 <at> debbugs.gnu.org>; Fri, 31 Oct 2025 13:47:49 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761943663; x=1762548463; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=ovt6/LCqWj0CFLfv+cZfmZXIFKX3j6gQmxAtiOuHkWg=;
 b=DaQcvHb+2RCi6uNsDwdNccL69WUu4aE/iZ9UYtIqyyrv9mOrwb/vZJXmchREMYTUUj
 S94YLU1jh4bei/sgIf36YwaNYKXb8XNpZu5X1FRxGmUuKlI+yYLRIYiXlj6Qrnf48MDT
 jsSBAoSc1RkVLsryi9WXAGddSQ+unrjB9oNiDw8nigvboQhSHXBjtvOg0YvP0wr+S+b1
 xX8Luhm75oylaRh6mvmQF08NKltOSCNYuLMD44EgQr0XbmmOSrlPfGyfozzEsIf4vgKA
 yno8FpZwpcdQhENOmc0yfiSX0NzB7eQYhCaBnskAXglM/4Df8lBGzR4cXUpWcF+ogN2y
 tNpw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761943663; x=1762548463;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=ovt6/LCqWj0CFLfv+cZfmZXIFKX3j6gQmxAtiOuHkWg=;
 b=rq+6+g6xkPipjdTQqUcgtPL5D9PPufOC0ZvMoTpn2qmFIJBXPnFA3vKnOkBeBb7Viv
 fqIh0sBWeZD5F8/zNCjIsPrFnCeLoQMoSBn2TiTKv3xInZ9k4Z9FwCkYwZYzlyxyBa1z
 ZuJiseJPAcCx6RaoxtPVXRMrHVX9XSYnKJYpwYj1mXIDCNPDJf/SKHT8J8M3UjItyFSG
 EkfuVI5ZOaXMYE3Pb5OL002+LXg+ngPKM3VEoshnlF+z3JLLa9xj/QN2zTwjmpQxXNd6
 tPstG2AINZn8ZGa1+AFbtRTDw7jng8FK2+cEajcjrWD84tvn+pfSH50ARZP+ByB+etku
 mF9Q==
X-Forwarded-Encrypted: i=1;
 AJvYcCX6CYYeQ23YmCazA1zcsxXhcYOM4dqs7olo1BwaMDpWstpFQumW1AFVnEXPWJsPta+JUA6Ppw==@debbugs.gnu.org
X-Gm-Message-State: AOJu0YxOokzox0GX9eLphskx+ZJLdg2YBfLv4YXxpr+PAMEchaDDnVC/
 +AyP3BGZBZETdD3i3B9ecLaI4u+ADSsqg4NM/53hf5nGig2taPC7+tOhHOl9FRIu
X-Gm-Gg: ASbGncuUK9mtZBMCpAn1YB4s23t6sQM+yAMGZbKsZv+c+zxO+GJH8BpeMThy71mCZb+
 +jgN+NQySGmNc4wyFi6OI3PoZsu9zgJROJX/xDZV+dN4400f0pci79CwGkbvO2AQNyLkUofJ8+B
 MCHEKBcq917aJcJapMGbHw91b2zJQATq725RnFRgIbP7gt9yB2UJDkmxwDkWV/g2IhqTwqDohql
 xLStGryoGt2XKb//5kY9WwgRGSh5lWIvL6X3Hqta+OYK7dt7f6FSZMChcE4NzugQUa+pSQ+GrM5
 0cFSiXjlXKbtmw8I4r8buz6fqXwFkPcOKz6HEy+50KDk4L2xiV366bSwGwbG9gLF2zH84EIGLj0
 c0F+W4P1uxrAqq7qOCFPZ2WZOCfER0kIv/g8KB0D7veeWyxfhgq27nvSMlCjryZyJ3mLPgrlpRP
 IulnkN
X-Google-Smtp-Source: AGHT+IFTGUkbzjviNDZIrYEVM7GIAxXgnSJao3Iw7LeY2uGY2+F9nbrccsMxw/Gk8m4joK9TNGtwng==
X-Received: by 2002:a05:690e:4083:b0:63e:914:28c8 with SMTP id
 956f58d0204a3-63f9a284e42mr2266974d50.68.1761943663243; 
 Fri, 31 Oct 2025 13:47:43 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 956f58d0204a3-63f96a50f23sm758853d50.14.2025.10.31.13.47.41
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Fri, 31 Oct 2025 13:47:42 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Juri Linkov <juri@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <87wm4bbjk1.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN> <87frb0qsng.fsf@HIDDEN>
 <87ecqk73sh.fsf@HIDDEN> <875xbw5i7q.fsf@HIDDEN>
 <874irgrxwq.fsf@HIDDEN> <87wm4bbjk1.fsf@HIDDEN>
Date: Fri, 31 Oct 2025 14:47:39 -0600
Message-ID: <87cy62dcic.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 79671
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>, Eli Zaretskii <eliz@HIDDEN>,
 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

--=-=-=
Content-Type: text/plain

Juri Linkov <juri@HIDDEN> writes:

> Yes, I see, because it keeps all existing non-nil values using 'or':
>
>   (setq hs-block-end-regexp (or hs-block-end-regexp
>                                 (hs--get-mode-value 'end 2)
>                                 "\\s)")
>         hs-c-start-regexp (or hs-c-start-regexp
>                               (hs--get-mode-value 'c-start 3)
>
> But it might be less reliable when nil values are required for a ts-mode
> to work properly, where non-ts non-nil values might interfere.
>
> It would be better to check if a buffer-local value is already set,
> and then not to override it with something like:
>
>   (setq hs-block-end-regexp (if (local-variable-p 'hs-block-end-regexp)
>                                 hs-block-end-regexp
>                               (or (hs--get-mode-value 'end 2)
>                                   "\\s)"))
>         hs-c-start-regexp (if (local-variable-p 'hs-c-start-regexp)
>                               hs-c-start-regexp
>                             (hs--get-mode-value 'c-start 3)

Fine, i've updated the patch, it should not override the variables that
are important for treesit, some variables such as
`hs-adjust-block-beginning` defaulted to `identity` before, and changing
it to nil will break hideshow.

Also i added a new value as replacement for `hs-inside-comment-p`, which
was redundant.


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow-Rewrite-hs-special-modes-alist.patch

From faa58b2284de53a46a71d356fa9afd1c7c3b6001 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Mon, 13 Oct 2025 18:45:21 -0600
Subject: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'

Rewrite the format in 'hs-special-modes-alist' to make easier to
exclude some values, add support for settings inheritance
according to current major mode and parents, and support string
hiding for lisp modes.

Bug#79671

* lisp/progmodes/hideshow.el (hs-modes-alist): New variable.
(hs-special-modes-alist): Mark as obsolete.
(hs-forward-sexp-func, hs-adjust-block-beginning)
(hs-find-block-beginning-func, hs-find-next-block-func)
(hs-looking-at-block-start-p-func): Set default values to nil.
(hs-inside-comment-p): Remove function.
(hs-adjust-block-end, hs-treesit-things): New buffer-local
variables.
(hs-block-positions): Minor updates.
(hs--get-mode-value): New function.
(hs-grok-mode-type): Rewrite.
* lisp/progmodes/f90.el (hs-special-modes-alist):
* lisp/progmodes/fortran.el (hs-special-modes-alist):
* lisp/progmodes/icon.el (icon-mode):
* lisp/progmodes/lua-mode.el (lua-mode):
* lisp/progmodes/python.el (python-base-mode):
* lisp/progmodes/verilog-mode.el (verilog-mode):
* lisp/progmodes/vhdl-mode.el (vhdl-hs-minor-mode): Rewrite
settings.
* lisp/progmodes/python.el (python-ts-hs-adjust-block-end-fn):
New function.
* lisp/treesit.el (treesit-hs-block-end)
(treesit-hs-find-block-beginning, treesit-hs-find-next-block)
(treesit-hs-looking-at-block-start-p): Minor updates.
* doc/emacs/programs.texi (Hideshow):
* etc/NEWS: Document changes.
---
 doc/emacs/programs.texi        |   5 +-
 etc/NEWS                       |   6 +
 lisp/progmodes/f90.el          |  12 +-
 lisp/progmodes/fortran.el      |  12 +-
 lisp/progmodes/hideshow.el     | 257 +++++++++++++++++++++++----------
 lisp/progmodes/icon.el         |  12 +-
 lisp/progmodes/lua-mode.el     |  10 +-
 lisp/progmodes/python.el       |  49 +++++--
 lisp/progmodes/verilog-mode.el |  12 +-
 lisp/progmodes/vhdl-mode.el    |  10 +-
 lisp/textmodes/mhtml-mode.el   |   2 +-
 lisp/treesit.el                |  15 +-
 12 files changed, 264 insertions(+), 138 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index f42f40fa28f..12bde32be05 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1735,7 +1735,7 @@ Hideshow
 @vindex hs-indicator-maximum-buffer-size
 @vindex hs-isearch-open
 @vindex hs-hide-block-behavior
-@vindex hs-special-modes-alist
+@vindex hs-modes-alist
   These variables can be used to customize Hideshow mode:
 
 @table @code
@@ -1782,6 +1782,9 @@ Hideshow
 nor comments).  The default value is @code{code}.
 @end table
 
+All necessary settings for each mode can be found in the variable
+@code{hs-modes-alist}.
+
 @node Symbol Completion
 @section Completion for Symbol Names
 @cindex completion (symbol names)
diff --git a/etc/NEWS b/etc/NEWS
index f61825f531b..f5dfa24d2b9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1069,6 +1069,12 @@ should hide a block.  If set to 'after-bol', hide the innermost block to
 which the current line belongs.  If set to 'after-cursor', hide the block
 after cursor position.  By default this is set to 'after-bol'.
 
++++
+*** The variable 'hs-special-modes-alist' is now obsolete.
+Use the new variable 'hs-modes-alist' instead, which supports mode
+hierarchy for each value.
+
+
 ** C-ts mode
 
 +++
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index 96626600d55..c3158069dcd 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -930,7 +930,7 @@ f90-end-block-re
                         "block" "critical") t)
           "\\_>")
   "Regexp matching the end of an F90 \"block\", from the line start.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
 ;; Ignore the fact that FUNCTION, SUBROUTINE, WHERE, FORALL have a
 ;; following "(".  DO, CASE, IF can have labels.
@@ -966,12 +966,12 @@ f90-start-block-re
   "Regexp matching the start of an F90 \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
-;; hs-special-modes-alist is autoloaded.
-(add-to-list 'hs-special-modes-alist
-             `(f90-mode ,f90-start-block-re ,f90-end-block-re
-                        "!" f90-end-of-block nil))
+;; hs-modes-alist is autoloaded.
+(add-to-list 'hs-modes-alist
+             `(f90-mode (start . ,f90-start-block-re) (end . ,f90-end-block-re)
+                        (c-start . "!") (forward-fn . f90-end-of-block)))
 
 
 ;; Imenu support.
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index d1f14fdf8fe..6eb75af01a3 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -549,7 +549,7 @@ fortran-end-block-re
           "\\|!\\|$\\)")
   "Regexp matching the end of a Fortran \"block\", from the line start.
 Note that only ENDDO is handled for the end of a DO-loop.  Used
-in the Fortran entry in `hs-special-modes-alist'.")
+in the Fortran entry in `hs-modes-alist'.")
 
 (defconst fortran-start-block-re
   (concat
@@ -582,11 +582,11 @@ fortran-start-block-re
   "Regexp matching the start of a Fortran \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the Fortran entry in `hs-special-modes-alist'.")
+Used in the Fortran entry in `hs-modes-alist'.")
 
-(add-to-list 'hs-special-modes-alist
-             `(fortran-mode ,fortran-start-block-re ,fortran-end-block-re
-                            "^[cC*!]" fortran-end-of-block nil))
+(add-to-list 'hs-modes-alist
+             `(fortran-mode (start . ,fortran-start-block-re) (end . ,fortran-end-block-re)
+                            (c-start . "^[cC*!]") (forward-fn . fortran-end-of-block)))
 
 
 (defvar fortran-mode-syntax-table
@@ -1247,7 +1247,7 @@ fortran-looking-at-if-then
           (goto-char i)
           (= (line-beginning-position) p)))))
 
-;; Used in hs-special-modes-alist.
+;; Used in hs-modes-alist.
 (defun fortran-end-of-block (&optional num)
   "Move point forward to the end of the current code block.
 With optional argument NUM, go forward that many balanced blocks.
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index 6158253ee53..13ec1bf65c9 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -370,30 +370,48 @@ hs-indicator-show
   :version "31.1")
 
 ;;;###autoload
-(defvar hs-special-modes-alist
-  ;; FIXME: Currently the check is made via
-  ;; (assoc major-mode hs-special-modes-alist) so it doesn't pay attention
-  ;; to the mode hierarchy.
-  '((c-mode "{" "}" "/[*/]" nil nil)
-    (c-ts-mode "{" "}" "/[*/]" nil nil)
-    (c++-mode "{" "}" "/[*/]" nil nil)
-    (c++-ts-mode "{" "}" "/[*/]" nil nil)
-    (bibtex-mode ("@\\S(*\\(\\s(\\)" 1))
-    (java-mode "{" "}" "/[*/]" nil nil)
-    (java-ts-mode "{" "}" "/[*/]" nil nil)
-    (js-mode "{" "}" "/[*/]" nil)
-    (js-ts-mode "{" "}" "/[*/]" nil)
-    (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil)
+(defvar hs-special-modes-alist nil)
+(make-obsolete-variable 'hs-special-modes-alist 'hs-modes-alist "31.1")
+
+;;;###autoload
+(defvar hs-modes-alist
+  '((c-mode (start . "\\s(\\|{\\|\"")
+            (end . "\\s)\\|}\\|\"")
+            (c-start . "/[*/]"))
+    (c++-mode (start . "\\s(\\|{\\|\"")
+              (end . "\\s)\\|}\\|\"")
+              (c-start . "/[*/]"))
+    (java-mode    (start . "\\s(\\|{\\|\"")
+                  (end . "\\s)\\|}\\|\"")
+                  (c-start . "/[*/]"))
+    (js-base-mode (start . "\\s(\\|{\\|\"")
+                  (end . "\\s)\\|}\\|\"")
+                  (c-start . "/[*/]"))
+    (bibtex-mode  (start . ("@\\S(*\\(\\s(\\)" 1)))
+    (sgml-mode (start . "<[^/>]*?") (end . "</[^/>]*[^/]>")
+               (c-start . "<!--") (forward-fn . sgml-skip-tag-forward))
+    (mhtml-mode (start . "{\\|<[^/>]*?") (end . "}\\|</[^/>]*[^/]>")
+                (forward-fn . mhtml-forward))
+    (lisp-data-mode (start . "\\s(\\|\"") (end . "\\s)\\|\""))
     ;; Add more support here.
     )
   "Alist for initializing the hideshow variables for different modes.
-Each element has the form
-  (MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC
-   FIND-BLOCK-BEGINNING-FUNC FIND-NEXT-BLOCK-FUNC
-   LOOKING-AT-BLOCK-START-P-FUNC).
+Each element is an alist with any of the cons-cells forms:
+ (MODE &optional
+       (start . START)
+       (end . END)
+       (c-start . COMMENT-START)
+       (forward-fn . FORWARD-SEXP-FUNC)
+       (adjust-beg-fn . ADJUST-BEG-FUNC)
+       (adjust-end-fn . ADJUST-END-FUNC)
+       (find-beg-fn . FIND-BLOCK-BEGINNING-FUNC)
+       (find-next-fn . FIND-NEXT-BLOCK-FUNC)
+       (look-start-fn . LOOKING-AT-BLOCK-START-P-FUNC)
+       (commentp . INSIDE-COMMENT-P-FUNC)
+       (treesit-things . TREESIT-THINGS))
 
 If non-nil, hideshow will use these values as regexps to define blocks
-and comments, respectively for major mode MODE.
+and comments, respectively for major mode MODE and its derivatives.
 
 START, END and COMMENT-START are regular expressions.  A block is
 defined as text surrounded by START and END.
@@ -403,7 +421,7 @@ hs-special-modes-alist
 MDATA-SELECTOR an integer that specifies which sub-match is the proper
 place to adjust point, before calling `hs-forward-sexp-func'.  Point
 is adjusted to the beginning of the specified match.  For example,
-see the `hs-special-modes-alist' entry for `bibtex-mode'.
+see the `hs-modes-alist' entry for `bibtex-mode'.
 
 For some major modes, `forward-sexp' does not work properly.  In those
 cases, FORWARD-SEXP-FUNC specifies another function to use instead.
@@ -411,6 +429,9 @@ hs-special-modes-alist
 See the documentation for `hs-adjust-block-beginning' to see what is the
 use of ADJUST-BEG-FUNC.
 
+See the documentation for `hs-adjust-block-end' to see what is the
+use of ADJUST-END-FUNC.
+
 See the documentation for `hs-find-block-beginning-func' to see
 what is the use of FIND-BLOCK-BEGINNING-FUNC.
 
@@ -420,7 +441,16 @@ hs-special-modes-alist
 See the documentation for `hs-looking-at-block-start-p-func' to
 see what is the use of LOOKING-AT-BLOCK-START-P-FUNC.
 
-If any of the elements is left nil or omitted, hideshow tries to guess
+See the documentation for `hs-inside-comment-p-func' to see what is the
+use of INSIDE-COMMENT-P-FUNC.
+
+TREESIT-THINGS is a thing defined in `treesit-thing-settings' to
+determine if current block at point is valid, see
+`treesit-thing-settings' for more information.
+
+All the elements support mode hierarchy.  If any of the elements is left
+nil or omitted, hideshow searches for a value defined in some parent
+mode in this alist; if no value is found, it tries to guess the
 appropriate values.  The regexps should not contain leading or trailing
 whitespace.  Case does not matter.")
 
@@ -548,7 +578,7 @@ hs-block-start-mdata-select
 (defvar-local hs-block-end-regexp nil
   "Regexp for end of block.")
 
-(defvar-local hs-forward-sexp-func #'forward-sexp
+(defvar-local hs-forward-sexp-func nil
   "Function used to do a `forward-sexp'.
 Should change for Algol-ish modes.  For single-character block
 delimiters -- ie, the syntax table regexp for the character is
@@ -556,7 +586,7 @@ hs-forward-sexp-func
 `forward-sexp'.  For other modes such as simula, a more specialized
 function is necessary.")
 
-(defvar-local hs-adjust-block-beginning #'identity
+(defvar-local hs-adjust-block-beginning nil
   "Function used to tweak the block beginning.
 The block is hidden from the position returned by this function,
 as opposed to hiding it from the position returned when searching
@@ -576,7 +606,18 @@ hs-adjust-block-beginning
 
 See `hs-c-like-adjust-block-beginning' for an example of using this.")
 
-(defvar-local hs-find-block-beginning-func #'hs-find-block-beginning
+(defvar-local hs-adjust-block-end nil
+  "Function used to tweak the block end.
+This is useful to ensure some characters such as parenthesis or curly
+braces get properly hidden in python-like modes.
+
+It is called with 1 argument which is the start position where the
+overlay will be created.
+
+It should return the last position to hide or nil.  If it returns nil,
+hideshow will guess the end position.")
+
+(defvar-local hs-find-block-beginning-func nil
   "Function used to do `hs-find-block-beginning'.
 It should reposition point at the beginning of the current block
 and return point, or nil if original point was not in a block.
@@ -585,7 +626,7 @@ hs-find-block-beginning-func
 Python, where regexp search and `syntax-ppss' check is not enough
 to find the beginning of the current block.")
 
-(defvar-local hs-find-next-block-func #'hs-find-next-block
+(defvar-local hs-find-next-block-func nil
   "Function used to do `hs-find-next-block'.
 It should reposition point at next block start.
 
@@ -601,7 +642,7 @@ hs-find-next-block-func
 Python, where regexp search is not enough to find the beginning
 of the next block.")
 
-(defvar-local hs-looking-at-block-start-p-func #'hs-looking-at-block-start-p
+(defvar-local hs-looking-at-block-start-p-func nil
   "Function used to do `hs-looking-at-block-start-p'.
 It should return non-nil if the point is at the block start.
 
@@ -610,7 +651,20 @@ hs-looking-at-block-start-p-func
 to check if the point is at the block start.")
 
 (defvar-local hs-inside-comment-p-func nil
-  "Function used to check if point is inside a comment.")
+  "Function used to check if point is inside a comment.
+If point is inside a comment, it should return a list containing the
+buffer position of the start and the end of the comment, otherwise
+return nil.
+
+A comment block can be hidden only if on its starting line there is only
+whitespace preceding the actual comment beginning.  If point is inside
+of a comment but this condition is not met, it can return a list having
+a nil as its car and the end of comment position as cdr.")
+
+(defvar-local hs-treesit-things nil
+  "Treesit things to check if point is at a valid block.
+The value should be a thing defined in `treesit-thing-settings' for the
+current buffer's major mode.")
 
 (defvar hs-headline nil
   "Text of the line where a hidden block begins, set during isearch.
@@ -703,8 +757,7 @@ hs-block-positions
           ;; `block-start' is the point at the end of the block
           ;; beginning, which may need to be adjusted
           (save-excursion
-            (goto-char (funcall (or hs-adjust-block-beginning #'identity)
-                                header-end))
+            (goto-char (funcall hs-adjust-block-beginning header-end))
             (setq block-beg (line-end-position)))
           ;; `block-end' is the point at the end of the block
           (hs-forward-sexp mdata 1)
@@ -716,7 +769,8 @@ hs-block-positions
                        (funcall hs-block-end-regexp)
                        (match-beginning 0))
                       (t (point))))
-          (cons block-beg block-end))))))
+          (cons block-beg
+                (or (funcall hs-adjust-block-end block-beg) block-end)))))))
 
 (defun hs--make-indicators-overlays (beg)
   "Helper function to make the indicators overlays."
@@ -924,18 +978,6 @@ hs-hide-block-at-point
           (goto-char (if end q (min p (match-end 0))))
           nil)))))
 
-(defun hs-inside-comment-p ()
-  "Return non-nil if point is inside a comment, otherwise nil.
-Actually, return a list containing the buffer position of the start
-and the end of the comment.  A comment block can be hidden only if on
-its starting line there is only whitespace preceding the actual comment
-beginning.  If we are inside of a comment but this condition is not met,
-we return a list having a nil as its car and the end of comment position
-as cdr."
-  (if (functionp hs-inside-comment-p-func)
-      (funcall hs-inside-comment-p-func)
-    (hs-inside-comment-p--default)))
-
 (defun hs-inside-comment-p--default ()
   (save-excursion
     ;; the idea is to look backwards for a comment start regexp, do a
@@ -987,43 +1029,100 @@ hs-inside-comment-p--default
           (when (>= (point) q)
             (list (and hideable p) (point))))))))
 
+(defun hs--get-mode-value (value &optional old-nth)
+  "Get VALUE for current major mode in `hs-modes-alist'.
+OLD-NTH is only used for backward compatibility with
+`hs-special-modes-alist'."
+  (if-let* (old-nth
+            (old-lookup (assoc major-mode hs-special-modes-alist)))
+      (nth old-nth old-lookup)
+    (catch 'hs-grok-exit
+      (dolist (modes (get major-mode 'derived-mode--all-parents))
+        ;; If we cannot find VALUE in current MODES, try to find it in
+        ;; the next mode in MODES
+        (if-let* ((list (assoc modes hs-modes-alist))
+                  (elm (alist-get value list)))
+            (throw 'hs-grok-exit elm))))))
+
 (defun hs-grok-mode-type ()
   "Set up hideshow variables for new buffers.
-If `hs-special-modes-alist' has information associated with the
+If `hs-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 (bound-and-true-p comment-start)
            (bound-and-true-p comment-end))
-      (let* ((lookup (assoc major-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 (or (nth 5 lookup) #'identity)
-              hs-find-block-beginning-func (or (nth 6 lookup)
-                                               #'hs-find-block-beginning)
-              hs-find-next-block-func (or (nth 7 lookup)
-                                          #'hs-find-next-block)
-              hs-looking-at-block-start-p-func
-              (or (nth 8 lookup)
-                  #'hs-looking-at-block-start-p)))
+      (let ((start-elem (ensure-list (hs--get-mode-value 'start 1))))
+        ;; If some these variables are already set, use them instead.
+        (setq
+         ;; handle (START-REGEXP MDATA-SELECT) and simple START-REGEXP
+         hs-block-start-regexp
+         (if (local-variable-p 'hs-block-start-regexp)
+             hs-block-start-regexp
+           (or (car start-elem) "\\s("))
+
+         hs-block-start-mdata-select
+         (if (local-variable-p 'hs-block-start-mdata-select)
+             hs-block-start-mdata-select
+           (or (cadr start-elem) 0))
+
+         hs-block-end-regexp
+         (if (local-variable-p 'hs-block-end-regexp)
+             hs-block-end-regexp
+           (or (hs--get-mode-value 'end 2) "\\s)"))
+
+         hs-c-start-regexp
+         (if (local-variable-p 'hs-c-start-regexp)
+             hs-c-start-regexp
+           (or (hs--get-mode-value 'c-start 3)
+               (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
+         (if (local-variable-p 'hs-forward-sexp-func)
+             hs-forward-sexp-func
+           (or (hs--get-mode-value 'forward-fn 4)
+               #'forward-sexp))
+
+         hs-adjust-block-beginning
+         (or (hs--get-mode-value 'adjust-fn 5) #'identity)
+
+         hs-adjust-block-end
+         (or (hs--get-mode-value 'adjust-end-fn) #'ignore)
+
+         hs-find-block-beginning-func
+         (if (local-variable-p 'hs-find-block-beginning-func)
+             hs-find-block-beginning-func
+           (or (hs--get-mode-value 'find-beg-fn 6)
+               #'hs-find-block-beginning))
+
+         hs-find-next-block-func
+         (if (local-variable-p 'hs-find-next-block-func)
+             hs-find-next-block-func
+           (or (hs--get-mode-value 'find-next-fn 7)
+               #'hs-find-next-block))
+
+         hs-looking-at-block-start-p-func
+         (if (local-variable-p 'hs-looking-at-block-start-p-func)
+             hs-looking-at-block-start-p-func
+           (or (hs--get-mode-value 'look-start-fn 8)
+               #'hs-looking-at-block-start-p))
+
+         hs-inside-comment-p-func
+         (if (local-variable-p 'hs-inside-comment-p-func)
+             hs-inside-comment-p-func
+           (or (hs--get-mode-value 'commentp)
+               #'hs-inside-comment-p--default))
+
+         hs-treesit-things
+         (or (hs--get-mode-value 'treesit-things) 'list)))
+
     (setq hs-minor-mode nil)
-    (error "%s Mode doesn't support Hideshow Minor Mode"
-           (format-mode-line mode-name))))
+    (error "%S doesn't support Hideshow Minor Mode" major-mode)))
 
 (defun hs-find-block-beginning ()
   "Reposition point at block-start.
@@ -1102,7 +1201,7 @@ hs-overlay-at
 (defun hs-already-hidden-p ()
   "Return non-nil if point is in an already-hidden block, otherwise nil."
   (save-excursion
-    (let ((c-reg (hs-inside-comment-p)))
+    (let ((c-reg (funcall hs-inside-comment-p-func)))
       (if (and c-reg (nth 0 c-reg))
           ;; point is inside a comment, and that comment is hideable
           (goto-char (nth 0 c-reg))
@@ -1170,7 +1269,7 @@ hs-hide-all
                          (eq (point) (match-beginning 0)))
 		   (goto-char (match-end 0)))))
            ;; found a comment, probably
-           (let ((c-reg (hs-inside-comment-p)))
+           (let ((c-reg (funcall hs-inside-comment-p-func)))
              (when (and c-reg (car c-reg))
                (if (hs-hideable-region-p (car c-reg) (nth 1 c-reg))
                    (hs-hide-block-at-point t c-reg)
@@ -1196,7 +1295,7 @@ hs-hide-block
 `hs-hide-hook' is run.  See documentation for `run-hooks'."
   (interactive "P")
   (hs-life-goes-on
-   (let ((c-reg (hs-inside-comment-p)))
+   (let ((c-reg (funcall hs-inside-comment-p-func)))
      (cond
       ((and c-reg (or (null (nth 0 c-reg))
                       (not (hs-hideable-region-p (car c-reg) (nth 1 c-reg)))))
@@ -1246,7 +1345,7 @@ hs-show-block
         (hs--refresh-indicators ov-start ov-end)
         t))
     ;; not immediately obvious, look for a suitable block
-    (let ((c-reg (hs-inside-comment-p))
+    (let ((c-reg (funcall hs-inside-comment-p-func))
           p q)
       (cond (c-reg
              (when (car c-reg)
@@ -1309,7 +1408,7 @@ hs-hide-initial-comment-block
    (let ((c-reg (save-excursion
                   (goto-char (point-min))
                   (skip-chars-forward " \t\n\f")
-                  (hs-inside-comment-p))))
+                  (funcall hs-inside-comment-p-func))))
      (when c-reg
        (let ((beg (car c-reg)) (end (cadr c-reg)))
          ;; see if we have enough comment lines to hide
@@ -1341,10 +1440,8 @@ hs-minor-mode
   (setq hs-headline nil)
   (if hs-minor-mode
       (progn
-        ;; Use such heuristics that if one buffer-local variable
-        ;; is already defined, don't overwrite other variables too.
-        (unless (buffer-local-value 'hs-inside-comment-p-func (current-buffer))
-          (hs-grok-mode-type))
+        ;; Set the variables according to `hs-modes-alist'.
+        (hs-grok-mode-type)
         ;; Turn off this mode if we change major modes.
         (add-hook 'change-major-mode-hook
                   #'turn-off-hideshow
diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el
index dee57956ce7..2a5172609d9 100644
--- a/lisp/progmodes/icon.el
+++ b/lisp/progmodes/icon.el
@@ -167,12 +167,12 @@ icon-mode
   ;; imenu support
   (setq-local imenu-generic-expression icon-imenu-generic-expression)
   ;; hideshow support
-  ;; we start from the assertion that `hs-special-modes-alist' is autoloaded.
-  (unless (assq 'icon-mode hs-special-modes-alist)
-    (setq hs-special-modes-alist
-	  (cons '(icon-mode  "\\<procedure\\>" "\\<end\\>" nil
-			     icon-forward-sexp-function)
-		hs-special-modes-alist))))
+  ;; we start from the assertion that `hs-modes-alist' is autoloaded.
+  (unless (assq 'icon-mode hs-modes-alist)
+    (setq hs-modes-alist
+	  (cons '(icon-mode  (start . "\\<procedure\\>") (end . "\\<end\\>")
+                             (forward-fn . icon-forward-sexp-function))
+		hs-modes-alist))))
 
 ;; This is used by indent-for-comment to decide how much to
 ;; indent a comment in Icon code based on its context.
diff --git a/lisp/progmodes/lua-mode.el b/lisp/progmodes/lua-mode.el
index 01d91637cf0..07b3777c988 100644
--- a/lisp/progmodes/lua-mode.el
+++ b/lisp/progmodes/lua-mode.el
@@ -553,12 +553,12 @@ lua-mode
   (add-hook 'flymake-diagnostic-functions #'lua-flymake nil t)
 
   ;; Hide-show setup
-  (unless (assq 'lua-mode hs-special-modes-alist)
-    (add-to-list 'hs-special-modes-alist
+  (unless (assq 'lua-mode hs-modes-alist)
+    (add-to-list 'hs-modes-alist
                  `(lua-mode
-                   ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words) ; Start
-                   ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words) ; End
-                   nil lua-forward-sexp))))
+                   (start . ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words)) ; Start
+                   (end . ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words)) ; End
+                   (forward-fn . lua-forward-sexp)))))
 
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 5a96972caa7..9826edfc054 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -5912,6 +5912,22 @@ python-hideshow-find-next-block
         (beginning-of-line)
         (looking-at regexp)))))
 
+(defun python-ts-hs-adjust-block-end-fn (block-beg)
+  "Python-ts-mode specific `hs-adjust-block-end' function for `hs-minor-mode'.
+
+BLOCK-BEG is the beginning position where the hiding will be performed.
+
+This is only used to properly hide the block when there are not closing
+parens."
+  (unless (save-excursion
+            (goto-char block-beg)
+            (treesit-thing-at
+             (1- (point))
+             '(or "argument_list"
+                  (and anonymous "\\`[](),[{}]\\'")
+                  "string")))
+    (line-end-position)))
+
 
 ;;; Imenu
 
@@ -7339,21 +7355,24 @@ python-base-mode
                       #'python-eldoc-function))))
   (eldoc-add-command-completions "python-indent-dedent-line-backspace")
 
-  ;; TODO: Use tree-sitter to figure out the block in `python-ts-mode'.
-  (dolist (mode '(python-mode python-ts-mode))
-    (add-to-list
-     'hs-special-modes-alist
-     `(,mode
-       ,python-nav-beginning-of-block-regexp
-       ;; Use the empty string as end regexp so it doesn't default to
-       ;; "\\s)".  This way parens at end of defun are properly hidden.
-       ""
-       "#"
-       python-hideshow-forward-sexp-function
-       nil
-       python-nav-beginning-of-block
-       python-hideshow-find-next-block
-       python-info-looking-at-beginning-of-block)))
+  (add-to-list
+   'hs-modes-alist
+   `(python-mode
+     (start . ,python-nav-beginning-of-block-regexp)
+     ;; Use the empty string as end regexp so it doesn't default to
+     ;; "\\s)".  This way parens at end of defun are properly hidden.
+     (end . "")
+     (c-start . "#")
+     (forward-fn . python-hideshow-forward-sexp-function)
+     (find-beg-fn . python-nav-beginning-of-block)
+     (find-next-fn . python-hideshow-find-next-block)
+     (look-start-fn . python-info-looking-at-beginning-of-block)))
+
+  (add-to-list
+   'hs-modes-alist
+   '(python-ts-mode
+     (treesit-things . (or defun sexp))
+     (adjust-end-fn . python-ts-hs-adjust-block-end-fn)))
 
   (setq-local outline-regexp (python-rx (* space) block-start))
   (setq-local outline-level
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 2f5525786e1..81fecec806f 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -4363,12 +4363,12 @@ verilog-mode
   (when (and (boundp 'which-func-modes) (listp which-func-modes))
     (add-to-list 'which-func-modes 'verilog-mode))
   ;; hideshow support
-  (when (boundp 'hs-special-modes-alist)
-    (unless (assq 'verilog-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-            (cons '(verilog-mode "\\<begin\\>" "\\<end\\>" nil
-                                 verilog-forward-sexp-function)
-                  hs-special-modes-alist))))
+  (when (boundp 'hs-modes-alist)
+    (unless (assq 'verilog-mode hs-modes-alist)
+      (setq hs-modes-alist
+            (cons '(verilog-mode (beg . "\\<begin\\>") (end . "\\<end\\>")
+                                 (forward-fn . verilog-forward-sexp-function))
+                  hs-modes-alist))))
 
   (add-hook 'completion-at-point-functions
             #'verilog-completion-at-point nil 'local)
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 593a83ceffa..82e6f41e07e 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -13282,11 +13282,11 @@ vhdl-hs-minor-mode
   (if (not (boundp 'hs-block-start-mdata-select))
       (vhdl-warning-when-idle "Install included `hideshow.el' patch first (see INSTALL file)")
     ;; initialize hideshow
-    (unless (assoc 'vhdl-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-	    (cons (list 'vhdl-mode vhdl-hs-start-regexp nil "--\\( \\|$\\)"
-			'vhdl-hs-forward-sexp-func nil)
-		  hs-special-modes-alist)))
+    (unless (assoc 'vhdl-mode hs-modes-alist)
+      (setq hs-modes-alist
+	    (cons `(vhdl-mode (start . ,vhdl-hs-start-regexp) (c-start . "--\\( \\|$\\)")
+			      (forward-fn . vhdl-hs-forward-sexp-func))
+		  hs-modes-alist)))
     (if (featurep 'xemacs) (make-local-hook 'hs-minor-mode-hook))
     (if vhdl-hide-all-init
 	(add-hook 'hs-minor-mode-hook #'hs-hide-all nil t)
diff --git a/lisp/textmodes/mhtml-mode.el b/lisp/textmodes/mhtml-mode.el
index e1ea73dc9ac..4ab560df6a8 100644
--- a/lisp/textmodes/mhtml-mode.el
+++ b/lisp/textmodes/mhtml-mode.el
@@ -306,7 +306,7 @@ mhtml--flyspell-check-word
         (flyspell-generic-progmode-verify)
       t)))
 
-;; Support for hideshow.el (see `hs-special-modes-alist').
+;; Support for hideshow.el (see `hs-modes-alist').
 (defun mhtml-forward (arg)
   "Move point forward past a structured expression.
 If point is on a tag, move to the end of the tag.
diff --git a/lisp/treesit.el b/lisp/treesit.el
index a8a515c434d..adc72156873 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -4230,7 +4230,7 @@ treesit-outline-level
 
 (defun treesit-hs-block-end ()
   "Tree-sitter implementation of `hs-block-end-regexp'."
-  (let* ((pred 'list)
+  (let* ((pred (bound-and-true-p hs-treesit-things))
          (thing (treesit-thing-at
                  (if (bobp) (point) (1- (point))) pred))
          (end (when thing (treesit-node-end thing)))
@@ -4243,7 +4243,7 @@ treesit-hs-block-end
 
 (defun treesit-hs-find-block-beginning ()
   "Tree-sitter implementation of `hs-find-block-beginning-func'."
-  (let* ((pred 'list)
+  (let* ((pred (bound-and-true-p hs-treesit-things))
          (thing (treesit-thing-at (point) pred))
          (beg (when thing (treesit-node-start thing)))
          (end (when beg (min (1+ beg) (point-max)))))
@@ -4260,17 +4260,18 @@ treesit-hs-find-next-block
           (when comments
             (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
                 'comment "\\`comment\\'")))
-         (pred (if comment-pred (append '(or list) (list comment-pred)) 'list))
+         (hs-things (bound-and-true-p hs-treesit-things))
+         (pred (append `(or ,hs-things) (when comment-pred (list comment-pred))))
          ;; `treesit-navigate-thing' can't find a thing at bobp,
          ;; so use `treesit-thing-at' to match at bobp.
          (current (treesit-thing-at (point) pred))
          (beg (or (and current (eq (point) (treesit-node-start current)) (point))
                   (treesit-navigate-thing (point) 1 'beg pred)))
-         ;; Check if we found a list or a comment
-         (list-thing (when beg (treesit-thing-at beg 'list)))
+         ;; Check if we found a block or a comment
+         (block-thing (when beg (treesit-thing-at beg hs-things)))
          (comment-thing (when beg (treesit-thing-at beg comment-pred)))
          (comment-p (and comment-thing (eq beg (treesit-node-start comment-thing))))
-         (thing (if comment-p comment-thing list-thing))
+         (thing (if comment-p comment-thing block-thing))
          (end (if thing (min (1+ (treesit-node-start thing)) (point-max)))))
     (when (and end (<= end maxp))
       (goto-char end)
@@ -4282,7 +4283,7 @@ treesit-hs-find-next-block
 
 (defun treesit-hs-looking-at-block-start-p ()
   "Tree-sitter implementation of `hs-looking-at-block-start-p-func'."
-  (let* ((pred 'list)
+  (let* ((pred (bound-and-true-p hs-treesit-things))
          (thing (treesit-thing-at (point) pred))
          (beg (when thing (treesit-node-start thing)))
          (end (min (1+ (point)) (point-max))))
-- 
2.51.0


--=-=-=
Content-Type: text/plain


-- 
- E.G via Gnus and Org.

--=-=-=--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 31 Oct 2025 07:53:50 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Oct 31 03:53:50 2025
Received: from localhost ([127.0.0.1]:40065 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vEjxD-0003n3-5j
	for submit <at> debbugs.gnu.org; Fri, 31 Oct 2025 03:53:50 -0400
Received: from mout-p-201.mailbox.org ([2001:67c:2050:0:465::201]:36878)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vEjwv-0003m8-Tu
 for 79671 <at> debbugs.gnu.org; Fri, 31 Oct 2025 03:53:37 -0400
Received: from smtp2.mailbox.org (smtp2.mailbox.org [10.196.197.2])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4cyYBT1S36z9tGl;
 Fri, 31 Oct 2025 08:53:21 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1761897201;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
 in-reply-to:in-reply-to:references:references;
 bh=pKuPCtdr0S7CX84sigN9HHFtToFPgKjynxGDx1yuzeU=;
 b=cke7xMwnOzH3fVEsKSU8GKj4CwKwbCPNyXjDfIi58OPaMH6kCNZtP4RGHYkEK2UiJxINOM
 pjr4EgF0ExsFhbaZiMgPwg/UlCXUdAvviF8yv28vpLaATmTy+TFgEAYrV6ysBNcG6DHh34
 uQi6LviyMHkOSG0QkemCVetGjfHWKE5sr0t1RkeBSCb1gnRdcF54ZGA4b4ixZ0z57Vvpbb
 DQjH19QRdV1BywjAp7XNweK3YgeGokKucPZ1HNDyVL61q5MDPmHnT7Tevk9nHiVMWZ/Mi8
 /sR3ndTskj2IxpKbt869Z9tz5BInrby0ipX6RRoqBn7lKV5S6AccRj8524AwZA==
From: Juri Linkov <juri@HIDDEN>
To: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <874irgrxwq.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN> <87frb0qsng.fsf@HIDDEN>
 <87ecqk73sh.fsf@HIDDEN> <875xbw5i7q.fsf@HIDDEN>
 <874irgrxwq.fsf@HIDDEN>
Date: Fri, 31 Oct 2025 09:46:06 +0200
Message-ID: <87wm4bbjk1.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>, Eli Zaretskii <eliz@HIDDEN>,
 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

>>     (setq-local hs-c-start-regexp nil
>>                 hs-block-start-regexp nil
>>                 hs-block-start-mdata-select 0
>>                 hs-block-end-regexp #'treesit-hs-block-end
>>                 hs-forward-sexp-func #'forward-list
>>                 hs-adjust-block-beginning nil
>>                 hs-find-block-beginning-func #'treesit-hs-find-block-beginning
>>                 hs-find-next-block-func #'treesit-hs-find-next-block
>>                 hs-looking-at-block-start-p-func #'treesit-hs-looking-at-block-start-p
>>                 hs-inside-comment-p-func #'treesit-hs-inside-comment-p)
>
> What kind of problem?
>
> The only values it overrides here are `hs-adjust-block-beginning`
> `hs-block-start-regexp` and `hs-c-start-regexp`, because these are not
> used in treesit.

Yes, I see, because it keeps all existing non-nil values using 'or':

  (setq hs-block-end-regexp (or hs-block-end-regexp
                                (hs--get-mode-value 'end 2)
                                "\\s)")
        hs-c-start-regexp (or hs-c-start-regexp
                              (hs--get-mode-value 'c-start 3)

But it might be less reliable when nil values are required for a ts-mode
to work properly, where non-ts non-nil values might interfere.

It would be better to check if a buffer-local value is already set,
and then not to override it with something like:

  (setq hs-block-end-regexp (if (local-variable-p 'hs-block-end-regexp)
                                hs-block-end-regexp
                              (or (hs--get-mode-value 'end 2)
                                  "\\s)"))
        hs-c-start-regexp (if (local-variable-p 'hs-c-start-regexp)
                              hs-c-start-regexp
                            (hs--get-mode-value 'c-start 3)




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 30 Oct 2025 19:29:43 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Oct 30 15:29:43 2025
Received: from localhost ([127.0.0.1]:37500 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vEYL8-0007XV-WF
	for submit <at> debbugs.gnu.org; Thu, 30 Oct 2025 15:29:43 -0400
Received: from mail-oa1-x41.google.com ([2001:4860:4864:20::41]:48537)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vEYL1-0007Wd-Bf
 for 79671 <at> debbugs.gnu.org; Thu, 30 Oct 2025 15:29:36 -0400
Received: by mail-oa1-x41.google.com with SMTP id
 586e51a60fabf-3c8fb195c23so1034405fac.1
 for <79671 <at> debbugs.gnu.org>; Thu, 30 Oct 2025 12:29:35 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761852568; x=1762457368; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=D2H1xeyNUeBO02TpysCyACOgz4UXhz+blNMvYFNbcmY=;
 b=LC3bRJnKxlN3UKjrBVtgk/F7uOFzYHYty621o63FL9dEk+sPWvcOedrHd4M2SSc+k6
 I/uqUNIjrPCqS3BLHGQ6GpwKqOVpDOCGchpo2rNpfUHvvut1/NklBRMHkEasmYUvyzfc
 UuICdd5u93TdbqfPd5p0198w77kr6W7rKUG3MONcNGHjLMaDhKQywb2XgC+fSwyr8Oig
 YEmBvX/Co9H5/iTNVZG1SdNuZugCHEb004zceMpiL34p3Hp4m5kiuIHXcrB31gv0j28S
 75DSB2ZzCB0vLdODtEvqVXYk3wKtxwtQxLumopGiLdJ8qbuupNLHcyPzKw8BL7WSB+2Z
 5CLg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761852568; x=1762457368;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=D2H1xeyNUeBO02TpysCyACOgz4UXhz+blNMvYFNbcmY=;
 b=cWDvQO8ZWSJx4kaMGeNbZNC2DE/LClDSi/rKR25A6UENL7CQxDbkMtZ6Y9WKULpZ4Q
 79hLqOcQIapftgfSdAmIFoI6lAYczaKYR/C1+25ZFMR4hFdo1DqbCQiXr4kjj6QZVJwr
 sRKN4/Bli+YqVcQqqMN5Ekb5tGDIybvMwTD9LNVccVUisDordQlUyWr5n/JPG//5OBxr
 hb/PfRIgPtyiJaMjiEJfQ6+ONcAm9K45VcCCOtY5DUYAa2rq+rL3rcTlu80l0HXoJJQZ
 6JVwob6cqv9RBuyc1J3+Q/OAwi3x8JtFh5SLWU0fbWEweMjj0ofzJ3YbOxErcaIEVf03
 nUkg==
X-Forwarded-Encrypted: i=1;
 AJvYcCXLA19iyieROlXkKCdbBycGrHBqs5TB42zKr6FBxytWAJIBuVv+TmOKljwZrXVOCh4uc8k5qg==@debbugs.gnu.org
X-Gm-Message-State: AOJu0YzkLGqWs3sMBjQAl06VWscAb0N+bMTEfOF5WFMuxFQ9Jwm7NSqO
 e1hA/ywBTCfU3V+Cegwz3fFXQueOywOqe1ASxJtKcH2jiKrD0i4cB24mgwc+6IE0
X-Gm-Gg: ASbGnct/j4K0gUmWOt0+jDsbiq4LWvx+HJxNLENRE3/TQce5YHQrHgKlkAO4Lr1nF4d
 E2fO1OZL3pXeXfpfFYfpUqouir7C7accRXdOCFghqHN3WJmd8HiSEvTo0vopsoPGj9wHsQG5wQ5
 BXciAHC/Od7Xt4yirDpEc3E+PKexd+D1wRUTfo+1UlbW2ovpeGNn2v61tHIrrM7ilFUQpM8c0Bo
 zU3KC1CW1Ha5GNQ6ZpsPKvmLhKPvwT8JRUxmsRXRcZUDBGVT6euZd9dnnXHCX3pdMtoKgQQhT14
 3SNckzukKuO17k9JcHm/pBDtrmMkVOEUDD6dgFjShAkB5NpbvnTuQA91jsFpyqZEAOqpP38uwPA
 SPf59yV5eQphXTvq4UkmdO8dbGuM5Jn4Z6RgL5UzKwN2M2AuIbzD6L9QE+1ueDgbV6yVmKEyvNY
 scmjD/1NJMY/vk2WQ=
X-Google-Smtp-Source: AGHT+IE/amwDKHB550NEQGizLSr2t0ajKVxxCTYCo9dneJ1RcSpJQ3UD+CKIqjbyIrfdlleFWlzXxQ==
X-Received: by 2002:a05:6870:332c:b0:396:3593:d19c with SMTP id
 586e51a60fabf-3daccf0f31emr433016fac.51.1761852568061; 
 Thu, 30 Oct 2025 12:29:28 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 586e51a60fabf-3d1e20f1396sm6173759fac.3.2025.10.30.12.29.27
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Thu, 30 Oct 2025 12:29:27 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Juri Linkov <juri@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <875xbw5i7q.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN> <87frb0qsng.fsf@HIDDEN>
 <87ecqk73sh.fsf@HIDDEN> <875xbw5i7q.fsf@HIDDEN>
Date: Thu, 30 Oct 2025 13:29:25 -0600
Message-ID: <874irgrxwq.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 79671
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>, Eli Zaretskii <eliz@HIDDEN>,
 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

Juri Linkov <juri@HIDDEN> writes:

> Actually, I take this comment back.  There is still a problem that
> the patch overrides these settings in 'treesit-major-mode-setup':
>
>     (setq-local hs-c-start-regexp nil
>                 hs-block-start-regexp nil
>                 hs-block-start-mdata-select 0
>                 hs-block-end-regexp #'treesit-hs-block-end
>                 hs-forward-sexp-func #'forward-list
>                 hs-adjust-block-beginning nil
>                 hs-find-block-beginning-func #'treesit-hs-find-block-beginning
>                 hs-find-next-block-func #'treesit-hs-find-next-block
>                 hs-looking-at-block-start-p-func #'treesit-hs-looking-at-block-start-p
>                 hs-inside-comment-p-func #'treesit-hs-inside-comment-p)

What kind of problem?

The only values it overrides here are `hs-adjust-block-beginning`
`hs-block-start-regexp` and `hs-c-start-regexp`, because these are not
used in treesit.

-- 
- E.G via Gnus and Org.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 30 Oct 2025 19:01:28 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Oct 30 15:01:28 2025
Received: from localhost ([127.0.0.1]:37398 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vEXtj-0006Hq-5x
	for submit <at> debbugs.gnu.org; Thu, 30 Oct 2025 15:01:28 -0400
Received: from mout-p-101.mailbox.org ([80.241.56.151]:47738)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vEXtZ-0006HS-2m
 for 79671 <at> debbugs.gnu.org; Thu, 30 Oct 2025 15:01:16 -0400
Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4cyD3M71fwz9tPg;
 Thu, 30 Oct 2025 20:01:03 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1761850864;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
 in-reply-to:in-reply-to:references:references;
 bh=K3ZkEJqG4/5r45BeejlEmDyZHiFH2ILsk7ouXfvBOvI=;
 b=JZmwmCWlY53u0ohXhBcsopzHGYosMjI1nIaXmcVUZMFqZ6cLOhszbBW5uJayLf+EfzYFv+
 BC9dkUMFSLjMfe9lmLzTbMpErEL/8AP2TEwDqkXS+u5ukhiKzUI1H/GRxHP0KKQ13kM3aE
 gMTIJfs74FxycpL6/IYCUhT21m12yti0eFSUGZAGkYA9osFfgLjxuDWGz46kj7p129YffY
 MvDGaN25Et/QtXO/fxHkETTt/x858ZWlcxVCnvagUgv+uBRmh0Bv5/RB748DDEot14iGIJ
 gnrIRKBt88OfDSL3gwxHWhFmezLUdOEiru2C3U7QmjOkJsMX9b0X1Mmp8ioB6g==
From: Juri Linkov <juri@HIDDEN>
To: Michael Heerdegen <michael_heerdegen@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <87ecqk73sh.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN> <87frb0qsng.fsf@HIDDEN>
 <87ecqk73sh.fsf@HIDDEN>
Date: Thu, 30 Oct 2025 20:58:20 +0200
Message-ID: <875xbw5i7q.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>,
 Eli Zaretskii <eliz@HIDDEN>, 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

>> | -        ;; Use such heuristics that if one buffer-local variable
>> | -        ;; is already defined, don't overwrite other variables too.
>> | -        (unless (buffer-local-value 'hs-inside-comment-p-func (current-buffer))
>> | -          (hs-grok-mode-type))
>> | +        ;; Set the variables according to `hs-modes-alist'.
>> | +        (hs-grok-mode-type)
>>
>> Does that mean that you suggest to drop the support of using file local
>> variables to configure or change the behavior of hideshow?
>
> This part was added recently as a hack to adapt hs-minor-mode to tree-sitter modes,
> since the only mode to set hs-inside-comment-p-func is treesit-major-mode-setup.
> So it's ok to remove this part.

Actually, I take this comment back.  There is still a problem that
the patch overrides these settings in 'treesit-major-mode-setup':

    (setq-local hs-c-start-regexp nil
                hs-block-start-regexp nil
                hs-block-start-mdata-select 0
                hs-block-end-regexp #'treesit-hs-block-end
                hs-forward-sexp-func #'forward-list
                hs-adjust-block-beginning nil
                hs-find-block-beginning-func #'treesit-hs-find-block-beginning
                hs-find-next-block-func #'treesit-hs-find-next-block
                hs-looking-at-block-start-p-func #'treesit-hs-looking-at-block-start-p
                hs-inside-comment-p-func #'treesit-hs-inside-comment-p)




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 30 Oct 2025 16:44:38 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Oct 30 12:44:38 2025
Received: from localhost ([127.0.0.1]:36820 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vEVlN-0004DN-H5
	for submit <at> debbugs.gnu.org; Thu, 30 Oct 2025 12:44:38 -0400
Received: from mail-oa1-x43.google.com ([2001:4860:4864:20::43]:44080)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vEVlF-0004Bi-NT
 for 79671 <at> debbugs.gnu.org; Thu, 30 Oct 2025 12:44:31 -0400
Received: by mail-oa1-x43.google.com with SMTP id
 586e51a60fabf-373b7e07182so846215fac.0
 for <79671 <at> debbugs.gnu.org>; Thu, 30 Oct 2025 09:44:29 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761842661; x=1762447461; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=WzEobEp0/LJnjzSzdq8iX5llPLI4kAf42e1iT+5POSA=;
 b=ba3Eyv/UGY5nT9ic6/DA3HA3H3RHFPjJx9FMzP1GJas4RDQpH99GTXvlrXZtiFM86S
 ax+gTW6kKPX1ykkjAOa8EbmliR602bCPfOTl7rIyM4P9gtxEke+a2W6wZ16eLiWfkbGT
 0z2cijfO4xa1wqVa/AYwQVLFikGXINjPkWgPG2SHH7ZusK/oX6M4C8LfQqQX9EHwJnlP
 OijImr1Rvde47CVQzqgyY5WDRCj7w9P9BecS86lpqiiwWMoPNrliDzYe8w2SWfUCYGUW
 jbzsbQnpLAN1KkV/84y0iLSCM+5HjXWCnBDJx2Gka9xrgiN1RaM7MrCAblvvoTtj6RhZ
 k1hw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761842661; x=1762447461;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=WzEobEp0/LJnjzSzdq8iX5llPLI4kAf42e1iT+5POSA=;
 b=wR0zOfXildsIJmu5fpT/X/q7HMnpEnEs1tzkMqqRK2Zo413Ttqz/JF72mjZQldReK8
 nSVGjklxiAnL1xHjYmvFS0rA0tBkPh+bRxBRV/15L+JsSteK3FhsQH2s6/GbJUcR9ZUl
 +zZOljfx6mbUIbk/uleJddX2DyrDXZ3kHPn0N1nUeUbgA1m1pPvcTGxn4Dw2rDMp3rgE
 lnnmsIjkwIZP2IBVEd0EWsDsH3lAk/eutAyQf0GXK11yZ5ox6OdHb7Y85QdQgX4jpTna
 KyLmNEXNEq0NS/SbEseP7EDMahd0G+/vLtKZcoievn4a59GqdHaoTSXDwBwcX/vULFfR
 nHaw==
X-Forwarded-Encrypted: i=1;
 AJvYcCWbEdu7blR9R8hKNPvJyOmqJafx+z2JP1LdStXatjRedE5i/H1sNARtAYppaTovk5jVYg2uOg==@debbugs.gnu.org
X-Gm-Message-State: AOJu0YxaNlmIW41jS5vRd4uvZ0IxKKaEQPtFsns+pjgB1yZm4eRopEhM
 39VLkxSTx7lijHBYWYjh518WoDiozwMbWO2NZmLKbp4MIK7xB4K/Y6nI
X-Gm-Gg: ASbGnctndqNxy9i+Y3ioACTFu28740S5ym+QoQO8w5g9oIkH3/X/Jqebq2M9kSjEA5g
 HgkkECmbeB0oBao+mEzlbVN4fQOmZ4AX79FSTIwYVSNIJx/LlHbzn0f9M2HF85cKelugmSlQ7gG
 QvMg6zcFQCAPKURN7OmlnGOQsbG0GvX68w2clAgPQR+qnpzVm1ivSQCp6IwXttULCXMdho/Dj5w
 a1G9qDIri3MsMM7sbKWJ+IvYg7oLAfhHF289v1C5V8hUqLMdzAutGVr4EXF7t8rDJPQNEPZtSxD
 eE2MrKne3qiuSiFTdlwGf/vcS2ExPfSDLBXKRz7CBCe9Z8KiSeqvGK++INSnwZi7mNy/EI0vtwK
 wVU5d/M6G7fIRV8/rE68k0gN+cYsvPuM7oL2aeDmzPJIjmHl/1o19G8mYLkft3jmu5rQ60P+V0D
 GiqowBWDZIWgdKRFQ=
X-Google-Smtp-Source: AGHT+IE7QlcYbTcew7f5C8dxW0flmgWfK2d/hB9KbHbSeIX4FzxncNmSGmZJo4iyuu/IdxDCq0PBlA==
X-Received: by 2002:a05:6870:d404:b0:349:de3c:bfc5 with SMTP id
 586e51a60fabf-3dac9f0f3e5mr108399fac.7.1761842660953; 
 Thu, 30 Oct 2025 09:44:20 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 586e51a60fabf-3d1e20f186bsm6005210fac.2.2025.10.30.09.44.18
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Thu, 30 Oct 2025 09:44:20 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
 of text editors" <bug-gnu-emacs@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <87frb0qsng.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN> <87frb0qsng.fsf@HIDDEN>
Date: Thu, 30 Oct 2025 10:44:16 -0600
Message-ID: <875xbwcpb3.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 79671
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>, Eli Zaretskii <eliz@HIDDEN>,
 79671 <at> debbugs.gnu.org, juri@HIDDEN
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
of text editors" <bug-gnu-emacs@HIDDEN> writes:

> | -and comments, respectively for major mode MODE.
> | +and comments, respectively for major mode MODE or current major mode
> | +parents.
>
> I find that sentence a bit hard to understand.  Could we say something
> like "for major mode MODE and any derived mode that has no separate
> entry" or something like that?  Or ask Eli.  It's confusing that you
> switch the perspective from what modes are all covered, with the
> perspective of finding a setting for the current buffer's mode.  Better
> try to keep one perspective.

I tried to explain that it also applies to major mode derivatives,
probably this can be changed to something like this?:

  "and comments, respectively for major mode MODE and its derivatives."


> | -(defvar-local hs-forward-sexp-func #'forward-sexp
> | +(defvar-local hs-forward-sexp-func nil
>   [etc..]
>
> Do I understand correctly that all of those variable default to nil now
> and every mode has to specify all the variables now, and there is no
> fallback?

No, there is a fallback:

              hs-forward-sexp-func (or hs-forward-sexp-func
                                       (hs--get-mode-value 'forward-fn 4)
                                       #'forward-sexp)
                                       ^^^^^^^^^^^^^^^

All these local variables fallback to their old default values, so it
should not break anything.

> Isn't that a regression - didn't some modes work with the old defaults
> in the past?

It should work fine, I've tested it with some 3rd-party modes.

-- 
- E.G via Gnus and Org.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 30 Oct 2025 16:44:56 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Oct 30 12:44:56 2025
Received: from localhost ([127.0.0.1]:36828 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vEVlf-0004Eh-Jt
	for submit <at> debbugs.gnu.org; Thu, 30 Oct 2025 12:44:56 -0400
Received: from lists.gnu.org ([2001:470:142::17]:55200)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vEVlZ-0004Dq-Tk
 for submit <at> debbugs.gnu.org; Thu, 30 Oct 2025 12:44:50 -0400
Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <eg642616@HIDDEN>)
 id 1vEVlS-0006m0-21
 for bug-gnu-emacs@HIDDEN; Thu, 30 Oct 2025 12:44:42 -0400
Received: from mail-oa1-x44.google.com ([2001:4860:4864:20::44])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <eg642616@HIDDEN>)
 id 1vEVlF-0003Zs-O3
 for bug-gnu-emacs@HIDDEN; Thu, 30 Oct 2025 12:44:41 -0400
Received: by mail-oa1-x44.google.com with SMTP id
 586e51a60fabf-373b7e07182so846214fac.0
 for <bug-gnu-emacs@HIDDEN>; Thu, 30 Oct 2025 09:44:25 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761842661; x=1762447461; darn=gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=WzEobEp0/LJnjzSzdq8iX5llPLI4kAf42e1iT+5POSA=;
 b=VisMAU2o5sLjkYZGXnr2OCZD6cvheAtKuEtEvXNy+QqVDCSNjNKk3iFV0M/hY33WQt
 85RSF0CdD0+UNgHz3rcR+GxDWxe9ZnyQDBZC+lmfWRoa5R7BfizRul/z/pmz5snuofiP
 LtN2t19sLdDzzFJ0/tAj7foGThnBikzKYtB2jquB6qgigDGVND+TKOtu4Cu/kbcDwnDL
 Uk5oKP4xhtOKKcUXx+IYNCSo1oMmsBfL+KEHh+3KBgmD9CQP4YyKy0mmvsgPlfAPt3Sl
 lx7vctYyp9mFshaHthjQAZ/+xvlu4wz7dKdUKmdFaFztja/385diKH0C/ZQyE77hkkX5
 FMZg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761842661; x=1762447461;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=WzEobEp0/LJnjzSzdq8iX5llPLI4kAf42e1iT+5POSA=;
 b=hP7KFt4bmmtzaGI25YcdzLBhMWN/NjjaCSEFq5gpMs7XV3l3PswV9Z9DW/r9R/8bNW
 sI0ET2oszELbf9/sfjmpPgUA0S6Eouamc5kd3/7H/5lTDI3sWPeE2udWQrb0LiDrdr9G
 91ISCCIbc1SwZjyaPJasMf8yngBVL/ZMTyww5EXd94aSq4lHcrNSLYc+dn5yJJVcgcJ3
 ifJS171yAWS5+Dk/k42YpXs0CfhdSkrNzN6tyIWmvePIuZMXdWA/0Nr2jfmha2wIK6y5
 Z23Klh/xObMfP1ZGIvUkJjF75WpTlbYicxeeJ7lTLGBiOODrjyxhjPOF5pxdRu2njLkx
 vxYg==
X-Gm-Message-State: AOJu0YyWADbEe9GMnZdR1ZPCP84p9Bv+/Zgb/sXKbg45bfQH3xK2CZxc
 Mdj6XzntckRQQA+OtwznbVbkch6evWswHkTSa3NuDa/wqhDir6eYtVsT
X-Gm-Gg: ASbGncuOx1kguQiIsmwZoN+V/h3RyFPiwX54fbivuuq7kZAiSvADpaBrnZj2hZSCRGc
 B6LDU7RssVqHRAQYA6Vj2ng/iF1IjvaYm5ZndGRLlKv8BfFksva8qw9V3igIjNfubeInLihHUkD
 JIuO/1W1VsG7oOxRfsZ8NHfseYwgsqE2cAB+W1h7bHmfdG30kugOgmDNuzycBy0R10QbpTtS3TZ
 /QZEUng+3Ftr0IxElgh+XD8dCTuISLRhbPArdbJaGl9OUDBN2x4NSu/+0LVSRwHHrLhyplv8wFs
 cZZM2pI1AQD9kwrEgHvUfArttJ0tqu+Y3DzG1tKtAS83+UeA7M1O+AXIjVpXeAE+NSc3RgpDL+Q
 GNOUg5aGbAX0f2exd20k8YXR4pZ0pGAXAT8vOSxrrCy53ubgMl9qKh8lDxD2fdS94hBrXCFA4BJ
 zQPV9WhwR9pWmJajc=
X-Google-Smtp-Source: AGHT+IE7QlcYbTcew7f5C8dxW0flmgWfK2d/hB9KbHbSeIX4FzxncNmSGmZJo4iyuu/IdxDCq0PBlA==
X-Received: by 2002:a05:6870:d404:b0:349:de3c:bfc5 with SMTP id
 586e51a60fabf-3dac9f0f3e5mr108399fac.7.1761842660953; 
 Thu, 30 Oct 2025 09:44:20 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 586e51a60fabf-3d1e20f186bsm6005210fac.2.2025.10.30.09.44.18
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Thu, 30 Oct 2025 09:44:20 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
 of text editors" <bug-gnu-emacs@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <87frb0qsng.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN> <87frb0qsng.fsf@HIDDEN>
Date: Thu, 30 Oct 2025 10:44:16 -0600
Message-ID: <875xbwcpb3.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50
MIME-Version: 1.0
Content-Type: text/plain
Received-SPF: pass client-ip=2001:4860:4864:20::44;
 envelope-from=eg642616@HIDDEN; helo=mail-oa1-x44.google.com
X-Spam_score_int: -17
X-Spam_score: -1.8
X-Spam_bar: -
X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,
 DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,
 FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001,
 RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001,
 T_SPF_HELO_TEMPERROR=0.01 autolearn=unavailable autolearn_force=no
X-Spam_action: no action
X-Spam-Score: 1.2 (+)
X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org",
 has NOT identified this incoming email as spam.  The original
 message has been attached to this so you can view it or label
 similar future email.  If you have any questions, see
 the administrator of that system for details.
 Content preview:  Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss
 army knife of text editors" writes: > | -and comments, respectively for major
 mode MODE. > | +and comments, respectively for major mode MODE or current
 major mode > | +parents. > > I find that sentence a bit hard to understand.
 Could we [...] 
 Content analysis details:   (1.2 points, 10.0 required)
 pts rule name              description
 ---- ---------------------- --------------------------------------------------
 -0.0 RCVD_IN_DNSWL_NONE     RBL: Sender listed at https://www.dnswl.org/,
 no trust [2001:470:142:0:0:0:0:17 listed in] [list.dnswl.org]
 0.0 FREEMAIL_FROM          Sender email is commonly abused enduser mail
 provider (eg642616[at]gmail.com)
 -0.0 SPF_HELO_PASS          SPF: HELO matches SPF record
 1.0 SPF_SOFTFAIL           SPF: sender does not match SPF record (softfail)
 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends
 in digit (eg642616[at]gmail.com)
X-Debbugs-Envelope-To: submit
Cc: Michael Heerdegen <michael_heerdegen@HIDDEN>, Eli Zaretskii <eliz@HIDDEN>,
 79671 <at> debbugs.gnu.org, juri@HIDDEN
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 0.2 (/)

Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
of text editors" <bug-gnu-emacs@HIDDEN> writes:

> | -and comments, respectively for major mode MODE.
> | +and comments, respectively for major mode MODE or current major mode
> | +parents.
>
> I find that sentence a bit hard to understand.  Could we say something
> like "for major mode MODE and any derived mode that has no separate
> entry" or something like that?  Or ask Eli.  It's confusing that you
> switch the perspective from what modes are all covered, with the
> perspective of finding a setting for the current buffer's mode.  Better
> try to keep one perspective.

I tried to explain that it also applies to major mode derivatives,
probably this can be changed to something like this?:

  "and comments, respectively for major mode MODE and its derivatives."


> | -(defvar-local hs-forward-sexp-func #'forward-sexp
> | +(defvar-local hs-forward-sexp-func nil
>   [etc..]
>
> Do I understand correctly that all of those variable default to nil now
> and every mode has to specify all the variables now, and there is no
> fallback?

No, there is a fallback:

              hs-forward-sexp-func (or hs-forward-sexp-func
                                       (hs--get-mode-value 'forward-fn 4)
                                       #'forward-sexp)
                                       ^^^^^^^^^^^^^^^

All these local variables fallback to their old default values, so it
should not break anything.

> Isn't that a regression - didn't some modes work with the old defaults
> in the past?

It should work fine, I've tested it with some 3rd-party modes.

-- 
- E.G via Gnus and Org.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 30 Oct 2025 16:29:01 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Oct 30 12:29:01 2025
Received: from localhost ([127.0.0.1]:36717 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vEVWG-0002t1-RE
	for submit <at> debbugs.gnu.org; Thu, 30 Oct 2025 12:29:01 -0400
Received: from mout-p-102.mailbox.org ([80.241.56.152]:42854)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vEVW7-0002s8-NA
 for 79671 <at> debbugs.gnu.org; Thu, 30 Oct 2025 12:28:54 -0400
Received: from smtp202.mailbox.org (smtp202.mailbox.org [10.196.197.202])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by mout-p-102.mailbox.org (Postfix) with ESMTPS id 4cy8gZ0436z9v9X;
 Thu, 30 Oct 2025 17:28:42 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1761841722;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
 in-reply-to:in-reply-to:references:references;
 bh=yXFeDLUwP/EF4IIswHniafbDK6kPI8YcadI0INUTMhI=;
 b=pJdKIULR7MMxBBD0sET6R05E7REod1rg6J7ABIyiTVts8B5JysYS97f8OriTP8bwfe+yT4
 eOdd8MSf81f0+rMWaRVVRzsCBOFxtNBQmWHFqRg3qTgYyl3dXa/4CNKC7/h4ENPr5uRZJT
 KDiiAtOGnFv8ntPBRAjiubaFcrpwbRtdZZR+5vCXEogkYGxiwOVvyt7VYG+x2TMLEbAckk
 U9GM769a49gg5o7V21mhHutq8BmUdSGh4p2DWkeOg43QxZ2lfuWldDNftL1ZvN16ChRavd
 +WSHQvJkvlNUPgDot12FX19kOyx/qtzD/G61ATxAnSOrsq4oc8U+md6YkoDONA==
From: Juri Linkov <juri@HIDDEN>
To: Michael Heerdegen <michael_heerdegen@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <87frb0qsng.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN> <87frb0qsng.fsf@HIDDEN>
Date: Thu, 30 Oct 2025 18:27:58 +0200
Message-ID: <87ecqk73sh.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>,
 Eli Zaretskii <eliz@HIDDEN>, 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

> | -        ;; Use such heuristics that if one buffer-local variable
> | -        ;; is already defined, don't overwrite other variables too.
> | -        (unless (buffer-local-value 'hs-inside-comment-p-func (current-buffer))
> | -          (hs-grok-mode-type))
> | +        ;; Set the variables according to `hs-modes-alist'.
> | +        (hs-grok-mode-type)
>
> Does that mean that you suggest to drop the support of using file local
> variables to configure or change the behavior of hideshow?

This part was added recently as a hack to adapt hs-minor-mode to tree-sitter modes,
since the only mode to set hs-inside-comment-p-func is treesit-major-mode-setup.
So it's ok to remove this part.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 30 Oct 2025 16:07:06 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Oct 30 12:07:06 2025
Received: from localhost ([127.0.0.1]:36626 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vEVB3-0001rI-Ue
	for submit <at> debbugs.gnu.org; Thu, 30 Oct 2025 12:07:06 -0400
Received: from mout.web.de ([212.227.15.4]:56297)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <michael_heerdegen@HIDDEN>)
 id 1vEVAu-0001qZ-7b
 for 79671 <at> debbugs.gnu.org; Thu, 30 Oct 2025 12:06:58 -0400
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=web.de;
 s=s29768273; t=1761840394; x=1762445194;
 i=michael_heerdegen@HIDDEN;
 bh=UO9C6gIazlRmnz1r7xCK+h2P4zXdbVbuhE0jNczR/Jk=;
 h=X-UI-Sender-Class:From:To:Cc:Subject:In-Reply-To:References:Date:
 Message-ID:MIME-Version:Content-Type:cc:content-transfer-encoding:
 content-type:date:from:message-id:mime-version:reply-to:subject:
 to;
 b=k8PByj+92sr2ie5Kj1No/wcPiLY3s6NOa/ZYi0hI7+nq0K7hdUlkyja8TD+NehTo
 h24rbLnCLx8fcOhdUoQxNhsFcB9IurP9Fs5+VQRJ7l/CdOLyxpmuuewZgnhjsfFtA
 MbTEU06wRBjkVunemov3R1x1OZxfdWoVgHMefK6M1c2tmsE+d2j49ojfJGot8Dr8m
 4gpNG75Z1/obq9A13sDIL0IDP55DIrqX7w0bt3Az3XcxkkswQmT8Cejm9vn7nCYi1
 d8pKaEvTCIeqr2gbQi21iyh9UJfCc+AKGZGtMnIyaSZ5TZ9SHJtE7xyJii7Y62RyL
 7wUGHTTBIthqV+CoHg==
X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6
Received: from drachen.dragon ([84.59.210.180]) by smtp.web.de (mrweb005
 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MC0PR-1vQLXr0tx7-00CMcD; Thu, 30
 Oct 2025 17:06:34 +0100
From: Michael Heerdegen <michael_heerdegen@HIDDEN>
To: Elijah Gabe =?utf-8?Q?P=C3=A9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <87ms5avg23.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN>
Date: Thu, 30 Oct 2025 17:08:19 +0100
Message-ID: <87frb0qsng.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13)
MIME-Version: 1.0
Content-Type: text/plain
X-Provags-ID: V03:K1:unOpFctcKeU2EeASKxGCjfhWHxE5Abi86W1N5IQJ87TVSRFmdjU
 4gvxgatwJAnx0BZqc+nw+6VkGrB05fjBb/WCtVtQssOi+t8uTkLJIanbdn3s0ye15qARS4G
 jIcz+LEbHdn7jTHQJq8BNDfIG6LZ7WL5zcufOFzBL/RVY8lRsFTEhxgeEBB0crS4L5lGXTu
 iivF1d0qLfBpEiuiU4A2A==
X-Spam-Flag: NO
UI-OutboundReport: notjunk:1;M01:P0:IjmjQV/DnMU=;RR6QXX/NsMZzuBMopsEHe4yBNpA
 e5T4ERfe2W7B0+12fRtOpb1rNj5t6ntthIFjbZMNR1E1FjGvKmmXYL5/vaie6mlZReI81tYt2
 lvdSnNo5kIOz7lUbFyqtPD4n3kohJpdre+0kAO0cPQPI/o64b1LNNRzaui0bqDJHR0A+Q2rxj
 eqdJuG9lVhDMsme4z/xB3L8Hyf5jmIm2MUY4Qtv7PTaGGIIUWjToOL/GMCeKOJZQrKetoA5kA
 UOJRIsByJYwgzte3TCPgSk5v6PqPnZhFy60AniULApOHksZnVs4FmzRbT2MOtWdi5nOdgGfSb
 fFAYU5mnPpRWrvt12BBsSwkVAfmn7CSgGqhhLEXz8yKqlY3PLx1AqyC3VBWc7GIXZayiazG1R
 lPidB0Rvw4WON+kEpCT8xyCGZ7mmLk0plY+Dpfc+7I+tX0A0Zv7xHz1QvfcJAA495nR527T0E
 os42JfhCJI8HxegR/DJBMxVtukIczEaiPIx6Xyirg0VwmFllr+ZPvzFt3TOT2P4kVoyVwGGJl
 PeAElSCKc96qFHoKoNY0vDErNXpug1aRoF0FovJr8i3VESpCkW1V8bWwms3Qbyxixv64ErNVw
 J6iLsCYI5piZz1v2VgUixKJ+PhnfLIh5vtfpDZn4ryyDsoOHXDGwKgH8Xtj3eSbcSRmGtu4Wd
 9bxLffqiJhqtiN6poTlisBCwiPtvgY+1x+CfbnqwnwYBC+mtD4bOkWxjWcqgvVsGXFxLQQrLb
 0NAnBvstGXlkEE1o5WbYiwA84oo/sCv3B7p2YeR2+zGRVdpAveQ3n14YqQlQ1+m2rKyrJ/LBV
 whnVFwjsnJjCkDqKTP3x/8m2tLr9oexfUaVwWBWByF7tXihL7fY9EDkP68SAKY7XeALhUQaOe
 VK4lnz/Pujbdl/APcImfwa8AGZmApx508WeylaI6gQzFXiE6gXSlUyA3fuMZLNgXFvV4CEoDo
 NygxxMTRX85eEzSIpmPDCs3VVPH8jBUxw06BwSVuyN8ZmGDP8N4fDYFm1aKv1/qR+n/gtv5E6
 Kv2EbEeNVUUn3xjUeKlnsd8j5AcOeLrogKGpobsuJzwFwiHJ2qnt3lff1ufZ2aKXMXDXm8H5Y
 u3Th/yXikVENHRanjlSPcuBeXSUkK2yFw4XOsUG+8f0fCUwhgwN/P2VjzQWZhxDJpwNG/6lRn
 zXXCiVmfK07iOdk9iQ1FAGCNu9lnCAJHA95aLI5E3SKIdODltwnkdVVzi3ChUa49HCpl9r5Vd
 hNnv/t58LraVhi/Nt1mLOjTDIeYOklyV6JPP9WQ3ne6POT8Q2FjPLrFR9BEgiVxdYu8P9sXKW
 GXQJM08bk7xO1a7shTvsGyx6YEPDpErUfcP3fC4Jgak9Hn3mlO1VXcUGiSlBcBupepVj0esOu
 llUUwVX6fnMIvIC5Z5CXSmPxZuk3qYPwtTTGiU+A0qPtzdjw5wsqe4+lmvyMQqJpreMmutAbg
 iwn/+xvyuqYJ3R/kzWMlFrtqJlI5sjVbQ2qznRrjHfO4O7ZeKPXXyUz+0Xd4pox2dY+gFFe8S
 ++25i1152bG6oPU7hgEcgkdj72F2MXwz6p6qCCesA5ObcV+FSTiwq0pri5/o4LAruL7NayIKk
 XznnjMRk1eFdYntydNi7/niv7ijYQHbOwVkq4uE89y3p3x/sdnPVgFUulbT9wg5X6KNiY5J3O
 NQNn9wKLq84bY/kb30FKzqFTPSMTlkEq0jC2sKTepOR8kSBMD0x3jJ5OjAMuy356AN7Icfrt1
 zr9V3/k4BvLWgUuIuHMB5qqgzVHezMDQUWkviOchIEpKcrVvDAdD2aR4PjV3UApT4IZvt/SVC
 iCyEA63IfVUwTIoGVDDew/Th3N0pnulqOvqXmOjb52jUmTMxHmo8u6s2/NQEcPQEG7eVGTB4m
 QVLDX7fZsW3JQiU3qKXlAd1aZmbRD8THEJFfAvG5XtPgSjEqP4AEHDZYdcxztyIYTWqk7Brzq
 vlJ0o25/Vpqls5nwhTjwx0mHq+svT29FEN1ONvKOomgBquj3rM9XmMNV4eS/6Wwe7PQnCIpPW
 f3lKBEvVbAzsKLvf14hLop4tiTQEjoxC3iFhIIMUrJn3R4HHNYFljsSLgxmV3H29I5X3KoPod
 +bfT7tnzNjtzzzZmnwzF+m3YuziuELpqxWv3EB93/4IIVm23aW23ZXTyzO57y3CppO0zsWRlB
 akKm41uVE1/at+47IQKKbX5kvlMROjR2IC1rugBH0cdLqVowYeVHxSQSLxGjaMS/pTm+tUpYj
 AfX4LYduUsFMmTQbkj6+KKt5uX/mCB22i1l+cAXRNLozytFpPADq5ZnwB6qjSoDUsBLG0Lpol
 Jdp7lTtC9Aw1T5ch4rLMWta+2DcQFKoLhFWS2mfDzLLsdHd3ZoePDpU0bAQQ4T10CrlSS2r7s
 rFteV0c/NkUVrG2njErM+XjkEF5nC2gu8PfEkPTp26s2zQHEKAF9Q5WaMCyufiiG2SfXOpnfO
 W6ZVuNhJbCD765D0kafcnWtNyMSSxYFmmh8Qhgnwey075EIFR3te2KguC4LuHMS5Lqv3fiBwq
 DZtCbznQVGynbCAGx7qPg4OOzZA6KJ1mz6pwQyre9zFzQrBOBMS1fl//cI+QB0n6MzuSfDL7H
 C4e/H91NJjSVvCZqUF5KYnICwaFdLj0iGzN92nTPxfV6a461+sClukBYcOLpuXXy34TQineUq
 46a2dpqna9WJSapqS3LrAHQgv4/Za7YbUKSbttoII1cFiVtaQ+MRt1Fc7Ez2kfAemKOtERXj7
 Z5B/ICUTsk6Bt2KAABPFwaup1DVRR+Y8wsuM0DEEnlzsn5HAbN/nYRhTVe663Kbv0n08x+tX1
 G/GBmiwTe6oszEo79ao84K1kheweFZuIBun20S5TJP8XPjn7eS1X39+LWZUzTG4LV288zYZk4
 qWIx5TbhpaYYTMpPu7NQ96SYov6BerENl7o1o8e3EMkufdnsaJgnR9Vu36Ly1fIDJMWDcuF4D
 6iMPn8yqWTIPMw8Tgau9E4lvLElLlyzK/ToEwAHS/I/rIbIYlqS7ZvzozjZ3/Mct588M9liHK
 xBPP1WXfT2QJN64El2TxQoGw4Pb+uZRRqEIz6J6wK2xX/filRXNtho2ub8JA+8anE5vCdlpMY
 CVn5MJWSlh9h7NWCum72JbgeIVkwvNyJXyJ0Vf9CvkqXQfPJkT8HuA6cF6KJgbIHcXfFehm1k
 0/EENhGgMNlvYC3ivrRPEeHZekBVFSLUMGCkha2GxDYi9rct90STU3kGgyUgKsl/to0EnoXlf
 k8bttdKMCSttsCtigfEdfHofs6oE0DsF0isIebIWpAzxfLHZ6y72s1NAjjm5zP2l94W9SZeBO
 6ubOmQ17S0b+6toF9QaNArcefXVcdQFXz0vpPfTpnbsYiDaZ2M0O9gurlRoJMPQq1fobmT8z8
 9xId8gi/q74WHCiNSK8Jzyx9rCdCzH0nXbJkldLh30vP3SpsC2UI2i2FRhgoxP1gpyo1mnmuu
 +USgX4BHra0JpFumiVM9gIrHah60V0V1cw5AvomubFpfFHVgKIQvfhufx73GBkcBHAxWZtxp0
 RGYqWb/jfTQluCOaudQEc9A9eLQybiyN5ibIUo21IvE7edHX45fJbXgijpCw4qTBIDzJ51bw1
 r23rvEz99TtXFplJ54zAsiW2nvkHgLKZb65MnNImtY/jjubK4q8p8WaEfmD9IzSyNbn3HbuHr
 flVwqufEW9IP+ehJYCcJYevM7H7bMKeMrn84SlPqZPs65lueBpZHEMRNnxSWL5UvDwOwKbHRJ
 M0XOc6oqcM8mDaQFm5tRTUkM0jPeYR5udEv813sD+eT+60mtEek2ZlNer4AS7RDixjd4bwXfU
 8R3VRiFpYdfZHNeyAizctyswOckpNr1ZBkBVtkSCC0L37S3LrDmocvqIBbne52xwxhHwg9P+1
 GTE9nL2zL1Goe0dcaHOGASQP1VCAwD5STov5OheA5GhlmYg0JVpyybQptWBjvKL2nE2esjKhY
 0jpuSzK2+acpChPnhcCZ2DoL9gSfam2uX/LmCyF9uIpJFeg21rcxSQoyf4r8P3tBXz9leXuIH
 VK9FM45EycBLsVMXkvczWuPsWAQSziMwZra/rKacN1aWQ6a5wDwCYvQNBAm/YGTDxzY7dC9dF
 FOY5jyMNblBFdN8QJBsfjFtMU3KiAizTMWv836NhuChG8xPYKEUqi/ID1wqqpI6FrCA9+7LrG
 5Q1akdVHBl847TlBeTkdYQQ31/LchKA7AAS6oj+QQgwfMkVPBCQ4dJzqyncJ4gnmmoPDT131F
 8/clRZr/u423U1YqKwjkY1RWVfCCw7C0xDF86uE/M0QgM7FYun7K4GMDWidmc8A0dnvXP80Mb
 ZFijNNOFGk4ncVSV8jwX0qn86657ZeGB0Pen4wxyR1/NWU68ydqE0kOX6UT3y0QuVHTQdNUah
 sIbQ65tbNaOc3Z70GEPCmKAqJuIVUdnogHFyG/kByPfeyNODkRlXXvgrmyLVINBUKavPz+b8z
 jhQpiPS8SgyDtrGNB/yYz+rzpdrEqY+6NkKNcW5Kw83BbINqOY8LJ4eYmkGBBMC2oE16uiunm
 DMFKRH2osy5uTIjCwuU8C39NcBC9H1HsoU6XUa9hoEvNIwqa0FbIUK9/Y9A1Cphsd4x9FlNZI
 JzR7J4YJdkO8kb/vCPfzZL9b9nX00hiW9wbNdOEGiLmpANY3DMI0J9MVv/IMDve0t/fh4w74W
 3tqvYfLuhS4fcU4ahX0cph2pCKEzmpyMit78DIgo/OFOa3RnmHawD5L5NgLTs5kITEfwm/f5Y
 Xz8RAOLGTkjbwDZah8XL0YhTRpkzIbPV1gbjqQseMZS8T3egEDxK9t4BSKM/a/dTDNXDBDtkz
 UbIVsenQBHXEYOYIxnH7iXmEducH75pypxGUFREaxVTW1n4bTW0Ew+T4UQwfNBjOZScSIyPy3
 D/S52sWkieS6lJj4xBbfoJypKmrdqKUzlcA2feHgWaTcqPaihxzP/KYdXdAahlIbVTwNof84m
 pZjZ9aCyb1gaP+E2BD6huRz4ryWpe2WSW+1DoaCk4Nd1SWIam38A4QIlYNsuuzlSNRO5CxlfG
 4hVHFnipTA6FUUsHj1FW/IPN6E=
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: Eli Zaretskii <eliz@HIDDEN>, 79671 <at> debbugs.gnu.org, juri@HIDDEN
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

Hello Elijah,

thanks for working on this.  I had a quick look.

| -and comments, respectively for major mode MODE.
| +and comments, respectively for major mode MODE or current major mode
| +parents.

I find that sentence a bit hard to understand.  Could we say something
like "for major mode MODE and any derived mode that has no separate
entry" or something like that?  Or ask Eli.  It's confusing that you
switch the perspective from what modes are all covered, with the
perspective of finding a setting for the current buffer's mode.  Better
try to keep one perspective.


| -(defvar-local hs-forward-sexp-func #'forward-sexp
| +(defvar-local hs-forward-sexp-func nil
  [etc..]

Do I understand correctly that all of those variable default to nil now
and every mode has to specify all the variables now, and there is no
fallback?  Isn't that a regression - didn't some modes work with the old
defaults in the past?

| -        ;; Use such heuristics that if one buffer-local variable
| -        ;; is already defined, don't overwrite other variables too.
| -        (unless (buffer-local-value 'hs-inside-comment-p-func (current-buffer))
| -          (hs-grok-mode-type))
| +        ;; Set the variables according to `hs-modes-alist'.
| +        (hs-grok-mode-type)

Does that mean that you suggest to drop the support of using file local
variables to configure or change the behavior of hideshow?


TIA,

Michael.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 29 Oct 2025 12:01:55 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Oct 29 08:01:54 2025
Received: from localhost ([127.0.0.1]:58179 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vE4sD-0004D2-T6
	for submit <at> debbugs.gnu.org; Wed, 29 Oct 2025 08:01:54 -0400
Received: from eggs.gnu.org ([2001:470:142:3::10]:49462)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <eliz@HIDDEN>) id 1vE4rs-0004CB-Of
 for 79671 <at> debbugs.gnu.org; Wed, 29 Oct 2025 08:01:38 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <eliz@HIDDEN>)
 id 1vE4ri-0004EY-GZ; Wed, 29 Oct 2025 08:01:22 -0400
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org;
 s=fencepost-gnu-org; h=MIME-version:References:Subject:In-Reply-To:To:From:
 Date; bh=UJRLUC7HQDVlG6P89Od4MxWN26ljVKpytnBzm6q66uw=; b=Ye9rXGKY7oHnnLtZb9AZ
 GjAldJrwktqcE5yoBs5YFlW3MtXqjxJpO0KmnWrfhpYp6TbyjtvMfelEc77iwlEJMQAktynOUzfJ+
 t6JEVWwU9wYBIobS1uTBvkpO9H84A+gUA2PjrPqXM2XCu5wLjduPrKdCM2nSFAdPVQ71VNXSMmAkz
 6YkeVespN+JiMR6pGcS7Q2FAcyRm3HREbdWWxmUbT5CE3Zc0j6eA3RypAN5gqHg5r6tW+GpfRiI8m
 +nM30+/NWqeOIbYqKskqOOKQLgsvE7hvwa7ddF3YC8/PHRV9zjrya+rUCDOvMkKYIv4qFAWh/XbXd
 xZkLlcItjx74/w==;
Date: Wed, 29 Oct 2025 14:01:15 +0200
Message-Id: <86jz0dor1w.fsf@HIDDEN>
From: Eli Zaretskii <eliz@HIDDEN>
To: Elijah Gabe =?utf-8?Q?P=C3=A9rez?= <eg642616@HIDDEN>
In-Reply-To: <87ms5avg23.fsf@HIDDEN> (message from Elijah Gabe
 =?utf-8?Q?P=C3=A9rez?= on Tue, 28 Oct 2025 16:04:36 -0600)
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
 <87ms5avg23.fsf@HIDDEN>
MIME-version: 1.0
Content-type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org, juri@HIDDEN
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

> From: Elijah Gabe Pérez <eg642616@HIDDEN>
> Cc: 79671 <at> debbugs.gnu.org,  juri@HIDDEN
> Date: Tue, 28 Oct 2025 16:04:36 -0600
> 
> Eli Zaretskii <eliz@HIDDEN> writes:
> 
> [...]
> 
> Thanks I've applied most of your suggestions.

Thanks, LGTM.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 28 Oct 2025 22:04:56 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Oct 28 18:04:56 2025
Received: from localhost ([127.0.0.1]:54839 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vDroE-0003HA-Kl
	for submit <at> debbugs.gnu.org; Tue, 28 Oct 2025 18:04:56 -0400
Received: from mail-oo1-xc42.google.com ([2607:f8b0:4864:20::c42]:43157)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vDro9-0003Gn-Av
 for 79671 <at> debbugs.gnu.org; Tue, 28 Oct 2025 18:04:51 -0400
Received: by mail-oo1-xc42.google.com with SMTP id
 006d021491bc7-6566a8d8d78so166859eaf.0
 for <79671 <at> debbugs.gnu.org>; Tue, 28 Oct 2025 15:04:49 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761689082; x=1762293882; darn=debbugs.gnu.org;
 h=mime-version:message-id:date:references:in-reply-to:subject:cc:to
 :from:from:to:cc:subject:date:message-id:reply-to;
 bh=7jzdNBU6Rdedd6URzVXan5yCXQxEV3od0TH7QHv+0jY=;
 b=RBDnl/ZZO17kKHUUC/WhjKz/IdnmCVZt1mdVbYHPRza1wWyd+JTZoMAThPsxdwbREI
 oKUHD7GT7Oyuj9Iz7zjNroQc9mD5OgPGG/RMM7colSO1j6XI+cd+THR9gqB1I0uLojel
 c86cTA9qwjrmnXvHVgq9I8szw5K7iaRWB3ihGVaax3a6Rd/BP16YJXr+hwTpST8JfhAI
 B6j7ZD3sy9un+jQdcHoo7O3a2lOR9UNZzQFRPB9KJp5vBWEWDInZQe0a6NK0i3Bl8+hH
 918NQt98Xzw7ysce43gY4c3X8Hzca82QDaN+Zj0IgJATwrMcz66Icmm0civeUaWDRgVj
 dx2A==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761689082; x=1762293882;
 h=mime-version:message-id:date:references:in-reply-to:subject:cc:to
 :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
 bh=7jzdNBU6Rdedd6URzVXan5yCXQxEV3od0TH7QHv+0jY=;
 b=C1wh0jaVtk4K2f87SstzBDq6s88DUHGpG6CyqvVopK8WRJgYf7Y6TSLcyiILynKYhr
 rUs7x3hCqtJjLD4P/PhD8l55ZYbILmeRv2c5EYqVx1tjeZS5W+QjIkQzlFXqMg1ZNhYm
 3RtI9uIKABW352XaEhMn34jSSnG9B1llUP9CUlX8B9haMpbKhYve3SczRg9hyP21qc18
 9eu/HS2zLTjUpIj+hifYGErGLWsCx6nRqNHA9eECRsiK72omu80IUodPUN5m2rqpOLtw
 nLqLvIWl+0fdMaq6d8/5bnJURVcSYoqNDlGhmqnpjW69s8VVdY0kLPefsW2UtnsqAMIc
 nUbA==
X-Gm-Message-State: AOJu0Ywv0TMGtT786e0YVle4zAmuitg03rFtNFsNCuawkptMR2/V77Fi
 ci4RI6oh17hPrzYxDmhjwZ3mR+Lc1pFws5BQxr7J7hEM8xAS0FcqUqb8
X-Gm-Gg: ASbGncvOEjL9YxjJvWUT+gv+n4+Su5HqA1onhbJbic7Q1p8lZ7zeh2gsBR3OcV5LYbf
 Vuu7RERQVTaHsrLReX3C89POab6vPcr1j0ba0IFn/JeHskUVOiDc1U6S+hnUyjAHyGa6s16lwsG
 Ni6i1WZF/Ka00fVC0SXVDTU3v2ShSyk6Hl7dYpNN1Wbgz1EScP3UriT3jPl1rbpjsrcYV7qptrT
 /j8VNNSOh9D/P9mX68wjKnsmFJrsEkb4ZTPCVgDRswfJ0xg1hQHuWIv7QGC6GjMLFIbSNWPxUWa
 OP37/QiPPyKkrmxGngfEcRQ67Gn8kHrUuxpMJnUCD2zffmALJNT30jgNDkb1Yqz1sXoNWEJtNIB
 K577o6I1KE/0wfVoUNf1kdeMRXCiVgS/N/DXs0YOuA364xXT6tRS4Ki0Ad9Jfo0A/VsAy1Q==
X-Google-Smtp-Source: AGHT+IGxoRJR4nmNs3t7Nt3AfT7JmzSfORalVlD/ptL7EA0YpFi9qrPq8hw6cfPIrmha8kBj06FLCA==
X-Received: by 2002:a05:6808:2195:b0:439:9f9c:8021 with SMTP id
 5614622812f47-44f7ad92d0cmr396650b6e.25.1761689082201; 
 Tue, 28 Oct 2025 15:04:42 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 5614622812f47-44f78a8937esm356643b6e.3.2025.10.28.15.04.39
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Tue, 28 Oct 2025 15:04:41 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Eli Zaretskii <eliz@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <86h5vjp4uk.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN> <86h5vjp4uk.fsf@HIDDEN>
Date: Tue, 28 Oct 2025 16:04:36 -0600
Message-ID: <87ms5avg23.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org, juri@HIDDEN
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

--=-=-=
Content-Type: text/plain

Eli Zaretskii <eliz@HIDDEN> writes:

[...]

Thanks I've applied most of your suggestions.

>> +(defvar-local hs-adjust-block-end nil
>> +  "Function used to tweak the block end.
>> +This is useful to ensure some characters such as parenthesis or curly
>> +braces get properly hidden in python-like modes.
>> +
>> +It is called with 1 argument which is the hiding beginning position.
>                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> "which is the beginning position of the block"

This actually referred to the start position of the overlay, i've fixed
it.

>> +(defun python-ts-adjust-block-end-fn (block-beg)
>> +  "Python-ts-mode specific `hs-adjust-block-end' function for `hs-minor-mode'.
>> +
>> +BLOCK-BEG is the beginning position where the hiding will be performed.
>> +
>> +This is only used to ensure the block end position in function
>> +definitions and parens."
>
> I don't understand the last sentence.  What does this ensure?

It meant to fixing this bug in python, where hiding a function was
displayed like this:

#+begin_src python
def test_func(arg):
    return arg

def test_func(arg):[...]g
#+end_src

While in blocks like this, this did not happen:

#+begin_src python
var = {
"1": 1
"2": 2
}

var = {[...]}
#+end_src


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow-Rewrite-hs-special-modes-alist.patch

From 565b198aa1d9bddc8f261f4a891a5e0c165b9adb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Mon, 13 Oct 2025 18:45:21 -0600
Subject: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'

Rewrite the format in 'hs-special-modes-alist' to make easier to
exclude some values, add support for settings inheritance
according to current major mode and parents, and support string
hiding for lisp modes.

Bug#79671

* lisp/progmodes/hideshow.el (hs-modes-alist): New variable.
(hs-special-modes-alist): Mark as obsolete.
(hs-forward-sexp-func, hs-adjust-block-beginning)
(hs-find-block-beginning-func, hs-find-next-block-func)
(hs-looking-at-block-start-p-func): Set default values to nil.
(hs-adjust-block-end, hs-treesit-things): New buffer-local
variables.
(hs-block-positions): Minor updates.
(hs--get-mode-value): New function.
(hs-grok-mode-type): Rewrite.
* lisp/progmodes/f90.el (hs-special-modes-alist):
* lisp/progmodes/fortran.el (hs-special-modes-alist):
* lisp/progmodes/icon.el (icon-mode):
* lisp/progmodes/lua-mode.el (lua-mode):
* lisp/progmodes/python.el (python-base-mode):
* lisp/progmodes/verilog-mode.el (verilog-mode):
* lisp/progmodes/vhdl-mode.el (vhdl-hs-minor-mode): Rewrite
settings.
* lisp/progmodes/python.el (python-ts-hs-adjust-block-end-fn): New
function.
* lisp/treesit.el (treesit-hs-block-end)
(treesit-hs-find-block-beginning, treesit-hs-find-next-block)
(treesit-hs-looking-at-block-start-p): Minor updates.
* doc/emacs/programs.texi (Hideshow):
* etc/NEWS: Document changes.
---
 doc/emacs/programs.texi        |   5 +-
 etc/NEWS                       |   6 ++
 lisp/progmodes/f90.el          |  12 +--
 lisp/progmodes/fortran.el      |  12 +--
 lisp/progmodes/hideshow.el     | 154 +++++++++++++++++++++++----------
 lisp/progmodes/icon.el         |  12 +--
 lisp/progmodes/lua-mode.el     |  10 +--
 lisp/progmodes/python.el       |  49 +++++++----
 lisp/progmodes/verilog-mode.el |  12 +--
 lisp/progmodes/vhdl-mode.el    |  10 +--
 lisp/textmodes/mhtml-mode.el   |   2 +-
 lisp/treesit.el                |  15 ++--
 12 files changed, 196 insertions(+), 103 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index f42f40fa28f..12bde32be05 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1735,7 +1735,7 @@ Hideshow
 @vindex hs-indicator-maximum-buffer-size
 @vindex hs-isearch-open
 @vindex hs-hide-block-behavior
-@vindex hs-special-modes-alist
+@vindex hs-modes-alist
   These variables can be used to customize Hideshow mode:
 
 @table @code
@@ -1782,6 +1782,9 @@ Hideshow
 nor comments).  The default value is @code{code}.
 @end table
 
+All necessary settings for each mode can be found in the variable
+@code{hs-modes-alist}.
+
 @node Symbol Completion
 @section Completion for Symbol Names
 @cindex completion (symbol names)
diff --git a/etc/NEWS b/etc/NEWS
index f61825f531b..f5dfa24d2b9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1069,6 +1069,12 @@ should hide a block.  If set to 'after-bol', hide the innermost block to
 which the current line belongs.  If set to 'after-cursor', hide the block
 after cursor position.  By default this is set to 'after-bol'.
 
++++
+*** The variable 'hs-special-modes-alist' is now obsolete.
+Use the new variable 'hs-modes-alist' instead, which supports mode
+hierarchy for each value.
+
+
 ** C-ts mode
 
 +++
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index 96626600d55..c3158069dcd 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -930,7 +930,7 @@ f90-end-block-re
                         "block" "critical") t)
           "\\_>")
   "Regexp matching the end of an F90 \"block\", from the line start.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
 ;; Ignore the fact that FUNCTION, SUBROUTINE, WHERE, FORALL have a
 ;; following "(".  DO, CASE, IF can have labels.
@@ -966,12 +966,12 @@ f90-start-block-re
   "Regexp matching the start of an F90 \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
-;; hs-special-modes-alist is autoloaded.
-(add-to-list 'hs-special-modes-alist
-             `(f90-mode ,f90-start-block-re ,f90-end-block-re
-                        "!" f90-end-of-block nil))
+;; hs-modes-alist is autoloaded.
+(add-to-list 'hs-modes-alist
+             `(f90-mode (start . ,f90-start-block-re) (end . ,f90-end-block-re)
+                        (c-start . "!") (forward-fn . f90-end-of-block)))
 
 
 ;; Imenu support.
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index d1f14fdf8fe..6eb75af01a3 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -549,7 +549,7 @@ fortran-end-block-re
           "\\|!\\|$\\)")
   "Regexp matching the end of a Fortran \"block\", from the line start.
 Note that only ENDDO is handled for the end of a DO-loop.  Used
-in the Fortran entry in `hs-special-modes-alist'.")
+in the Fortran entry in `hs-modes-alist'.")
 
 (defconst fortran-start-block-re
   (concat
@@ -582,11 +582,11 @@ fortran-start-block-re
   "Regexp matching the start of a Fortran \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the Fortran entry in `hs-special-modes-alist'.")
+Used in the Fortran entry in `hs-modes-alist'.")
 
-(add-to-list 'hs-special-modes-alist
-             `(fortran-mode ,fortran-start-block-re ,fortran-end-block-re
-                            "^[cC*!]" fortran-end-of-block nil))
+(add-to-list 'hs-modes-alist
+             `(fortran-mode (start . ,fortran-start-block-re) (end . ,fortran-end-block-re)
+                            (c-start . "^[cC*!]") (forward-fn . fortran-end-of-block)))
 
 
 (defvar fortran-mode-syntax-table
@@ -1247,7 +1247,7 @@ fortran-looking-at-if-then
           (goto-char i)
           (= (line-beginning-position) p)))))
 
-;; Used in hs-special-modes-alist.
+;; Used in hs-modes-alist.
 (defun fortran-end-of-block (&optional num)
   "Move point forward to the end of the current code block.
 With optional argument NUM, go forward that many balanced blocks.
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index 6158253ee53..acdebb08b01 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -370,30 +370,40 @@ hs-indicator-show
   :version "31.1")
 
 ;;;###autoload
-(defvar hs-special-modes-alist
-  ;; FIXME: Currently the check is made via
-  ;; (assoc major-mode hs-special-modes-alist) so it doesn't pay attention
-  ;; to the mode hierarchy.
-  '((c-mode "{" "}" "/[*/]" nil nil)
-    (c-ts-mode "{" "}" "/[*/]" nil nil)
-    (c++-mode "{" "}" "/[*/]" nil nil)
-    (c++-ts-mode "{" "}" "/[*/]" nil nil)
-    (bibtex-mode ("@\\S(*\\(\\s(\\)" 1))
-    (java-mode "{" "}" "/[*/]" nil nil)
-    (java-ts-mode "{" "}" "/[*/]" nil nil)
-    (js-mode "{" "}" "/[*/]" nil)
-    (js-ts-mode "{" "}" "/[*/]" nil)
-    (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil)
+(defvar hs-special-modes-alist nil)
+(make-obsolete-variable 'hs-special-modes-alist 'hs-modes-alist "31.1")
+
+;;;###autoload
+(defvar hs-modes-alist
+  '((c-mode    (start . "{") (end . "}") (c-start . "/[*/]"))
+    (c++-mode  (start . "{") (end . "}") (c-start . "/[*/]"))
+    (java-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (bibtex-mode  (start . ("@\\S(*\\(\\s(\\)" 1)))
+    (js-base-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (sgml-mode (start . "<[^/>]*?") (end . "</[^/>]*[^/]>")
+               (c-start . "<!--") (forward-fn . sgml-skip-tag-forward))
+    (mhtml-mode (start . "{\\|<[^/>]*?") (end . "}\\|</[^/>]*[^/]>")
+                (forward-fn . mhtml-forward))
+    (lisp-data-mode (start . "\\s(\\|\"") (end . "\\s)\\|\""))
     ;; Add more support here.
     )
   "Alist for initializing the hideshow variables for different modes.
-Each element has the form
-  (MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC
-   FIND-BLOCK-BEGINNING-FUNC FIND-NEXT-BLOCK-FUNC
-   LOOKING-AT-BLOCK-START-P-FUNC).
+Each element is an alist with any of the cons-cells forms:
+ (MODE &optional
+       (start . START)
+       (end . END)
+       (c-start . COMMENT-START)
+       (forward-fn . FORWARD-SEXP-FUNC)
+       (adjust-beg-fn . ADJUST-BEG-FUNC)
+       (adjust-end-fn . ADJUST-END-FUNC)
+       (find-beg-fn . FIND-BLOCK-BEGINNING-FUNC)
+       (find-next-fn . FIND-NEXT-BLOCK-FUNC)
+       (look-start-fn . LOOKING-AT-BLOCK-START-P-FUNC)
+       (treesit-things . TREESIT-THINGS))
 
 If non-nil, hideshow will use these values as regexps to define blocks
-and comments, respectively for major mode MODE.
+and comments, respectively for major mode MODE or current major mode
+parents.
 
 START, END and COMMENT-START are regular expressions.  A block is
 defined as text surrounded by START and END.
@@ -403,7 +413,7 @@ hs-special-modes-alist
 MDATA-SELECTOR an integer that specifies which sub-match is the proper
 place to adjust point, before calling `hs-forward-sexp-func'.  Point
 is adjusted to the beginning of the specified match.  For example,
-see the `hs-special-modes-alist' entry for `bibtex-mode'.
+see the `hs-modes-alist' entry for `bibtex-mode'.
 
 For some major modes, `forward-sexp' does not work properly.  In those
 cases, FORWARD-SEXP-FUNC specifies another function to use instead.
@@ -411,6 +421,9 @@ hs-special-modes-alist
 See the documentation for `hs-adjust-block-beginning' to see what is the
 use of ADJUST-BEG-FUNC.
 
+See the documentation for `hs-adjust-block-end' to see what is the
+use of ADJUST-END-FUNC.
+
 See the documentation for `hs-find-block-beginning-func' to see
 what is the use of FIND-BLOCK-BEGINNING-FUNC.
 
@@ -420,7 +433,13 @@ hs-special-modes-alist
 See the documentation for `hs-looking-at-block-start-p-func' to
 see what is the use of LOOKING-AT-BLOCK-START-P-FUNC.
 
-If any of the elements is left nil or omitted, hideshow tries to guess
+TREESIT-THINGS is a thing defined in `treesit-thing-settings' to
+determine if current block at point is valid, see
+`treesit-thing-settings' for more information.
+
+All the elements support mode hierarchy.  If any of the elements is left
+nil or omitted, hideshow searches for a value defined in some parent
+mode in this alist; if no value is found, it tries to guess the
 appropriate values.  The regexps should not contain leading or trailing
 whitespace.  Case does not matter.")
 
@@ -548,7 +567,7 @@ hs-block-start-mdata-select
 (defvar-local hs-block-end-regexp nil
   "Regexp for end of block.")
 
-(defvar-local hs-forward-sexp-func #'forward-sexp
+(defvar-local hs-forward-sexp-func nil
   "Function used to do a `forward-sexp'.
 Should change for Algol-ish modes.  For single-character block
 delimiters -- ie, the syntax table regexp for the character is
@@ -556,7 +575,7 @@ hs-forward-sexp-func
 `forward-sexp'.  For other modes such as simula, a more specialized
 function is necessary.")
 
-(defvar-local hs-adjust-block-beginning #'identity
+(defvar-local hs-adjust-block-beginning nil
   "Function used to tweak the block beginning.
 The block is hidden from the position returned by this function,
 as opposed to hiding it from the position returned when searching
@@ -576,7 +595,18 @@ hs-adjust-block-beginning
 
 See `hs-c-like-adjust-block-beginning' for an example of using this.")
 
-(defvar-local hs-find-block-beginning-func #'hs-find-block-beginning
+(defvar-local hs-adjust-block-end nil
+  "Function used to tweak the block end.
+This is useful to ensure some characters such as parenthesis or curly
+braces get properly hidden in python-like modes.
+
+It is called with 1 argument which is the start position where the
+overlay will be created.
+
+It should return the last position to hide or nil.  If it returns nil,
+hideshow will guess the end position.")
+
+(defvar-local hs-find-block-beginning-func nil
   "Function used to do `hs-find-block-beginning'.
 It should reposition point at the beginning of the current block
 and return point, or nil if original point was not in a block.
@@ -585,7 +615,7 @@ hs-find-block-beginning-func
 Python, where regexp search and `syntax-ppss' check is not enough
 to find the beginning of the current block.")
 
-(defvar-local hs-find-next-block-func #'hs-find-next-block
+(defvar-local hs-find-next-block-func nil
   "Function used to do `hs-find-next-block'.
 It should reposition point at next block start.
 
@@ -601,7 +631,7 @@ hs-find-next-block-func
 Python, where regexp search is not enough to find the beginning
 of the next block.")
 
-(defvar-local hs-looking-at-block-start-p-func #'hs-looking-at-block-start-p
+(defvar-local hs-looking-at-block-start-p-func nil
   "Function used to do `hs-looking-at-block-start-p'.
 It should return non-nil if the point is at the block start.
 
@@ -612,6 +642,11 @@ hs-looking-at-block-start-p-func
 (defvar-local hs-inside-comment-p-func nil
   "Function used to check if point is inside a comment.")
 
+(defvar-local hs-treesit-things nil
+  "Treesit things to check if point is at a valid block.
+The value should be a thing defined in `treesit-thing-settings' for the
+current buffer's major mode.")
+
 (defvar hs-headline nil
   "Text of the line where a hidden block begins, set during isearch.
 You can display this in the mode line by adding the symbol `hs-headline'
@@ -703,8 +738,7 @@ hs-block-positions
           ;; `block-start' is the point at the end of the block
           ;; beginning, which may need to be adjusted
           (save-excursion
-            (goto-char (funcall (or hs-adjust-block-beginning #'identity)
-                                header-end))
+            (goto-char (funcall hs-adjust-block-beginning header-end))
             (setq block-beg (line-end-position)))
           ;; `block-end' is the point at the end of the block
           (hs-forward-sexp mdata 1)
@@ -716,7 +750,8 @@ hs-block-positions
                        (funcall hs-block-end-regexp)
                        (match-beginning 0))
                       (t (point))))
-          (cons block-beg block-end))))))
+          (cons block-beg
+                (or (funcall hs-adjust-block-end block-beg) block-end)))))))
 
 (defun hs--make-indicators-overlays (beg)
   "Helper function to make the indicators overlays."
@@ -987,16 +1022,31 @@ hs-inside-comment-p--default
           (when (>= (point) q)
             (list (and hideable p) (point))))))))
 
+(defun hs--get-mode-value (value &optional old-nth)
+  "Get VALUE for current major mode in `hs-modes-alist'.
+OLD-NTH is only used for backward compatibility with
+`hs-special-modes-alist'."
+  (if-let* (old-nth
+            (old-lookup (assoc major-mode hs-special-modes-alist)))
+      (nth old-nth old-lookup)
+    (catch 'hs-grok-exit
+      (dolist (modes (get major-mode 'derived-mode--all-parents))
+        ;; If we cannot find VALUE in current MODES, try to find it in
+        ;; the next mode in MODES
+        (if-let* ((list (assoc modes hs-modes-alist))
+                  (elm (alist-get value list)))
+            (throw 'hs-grok-exit elm))))))
+
 (defun hs-grok-mode-type ()
   "Set up hideshow variables for new buffers.
-If `hs-special-modes-alist' has information associated with the
+If `hs-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 (bound-and-true-p comment-start)
            (bound-and-true-p comment-end))
-      (let* ((lookup (assoc major-mode hs-special-modes-alist))
-             (start-elem (or (nth 1 lookup) "\\s(")))
+      (let ((start-elem (or (hs--get-mode-value 'start 1) "\\s(")))
+
         (if (listp start-elem)
             ;; handle (START-REGEXP MDATA-SELECT)
             (setq hs-block-start-regexp (car start-elem)
@@ -1004,23 +1054,39 @@ hs-grok-mode-type
           ;; 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)
+
+        (setq hs-block-end-regexp (or hs-block-end-regexp
+                                      (hs--get-mode-value 'end 2)
+                                      "\\s)")
+              hs-c-start-regexp (or hs-c-start-regexp
+                                    (hs--get-mode-value 'c-start 3)
                                     (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 (or (nth 5 lookup) #'identity)
-              hs-find-block-beginning-func (or (nth 6 lookup)
+              hs-forward-sexp-func (or hs-forward-sexp-func
+                                       (hs--get-mode-value 'forward-fn 4)
+                                       #'forward-sexp)
+              hs-adjust-block-beginning (or hs-adjust-block-beginning
+                                            (hs--get-mode-value 'adjust-fn 5)
+                                            #'identity)
+              hs-adjust-block-end (or hs-adjust-block-end
+                                      (hs--get-mode-value 'adjust-end-fn 5)
+                                      #'ignore)
+              hs-find-block-beginning-func (or hs-find-block-beginning-func
+                                               (hs--get-mode-value 'find-beg-fn 6)
                                                #'hs-find-block-beginning)
-              hs-find-next-block-func (or (nth 7 lookup)
+              hs-find-next-block-func (or hs-find-next-block-func
+                                          (hs--get-mode-value 'find-next-fn 7)
                                           #'hs-find-next-block)
-              hs-looking-at-block-start-p-func
-              (or (nth 8 lookup)
-                  #'hs-looking-at-block-start-p)))
+              hs-looking-at-block-start-p-func (or hs-looking-at-block-start-p-func
+                                                   (hs--get-mode-value 'look-start-fn 8)
+                                                   #'hs-looking-at-block-start-p)
+              hs-treesit-things (or hs-treesit-things
+                                    (hs--get-mode-value 'treesit-things)
+                                    'list)))
     (setq hs-minor-mode nil)
     (error "%s Mode doesn't support Hideshow Minor Mode"
            (format-mode-line mode-name))))
@@ -1341,10 +1407,8 @@ hs-minor-mode
   (setq hs-headline nil)
   (if hs-minor-mode
       (progn
-        ;; Use such heuristics that if one buffer-local variable
-        ;; is already defined, don't overwrite other variables too.
-        (unless (buffer-local-value 'hs-inside-comment-p-func (current-buffer))
-          (hs-grok-mode-type))
+        ;; Set the variables according to `hs-modes-alist'.
+        (hs-grok-mode-type)
         ;; Turn off this mode if we change major modes.
         (add-hook 'change-major-mode-hook
                   #'turn-off-hideshow
diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el
index dee57956ce7..2a5172609d9 100644
--- a/lisp/progmodes/icon.el
+++ b/lisp/progmodes/icon.el
@@ -167,12 +167,12 @@ icon-mode
   ;; imenu support
   (setq-local imenu-generic-expression icon-imenu-generic-expression)
   ;; hideshow support
-  ;; we start from the assertion that `hs-special-modes-alist' is autoloaded.
-  (unless (assq 'icon-mode hs-special-modes-alist)
-    (setq hs-special-modes-alist
-	  (cons '(icon-mode  "\\<procedure\\>" "\\<end\\>" nil
-			     icon-forward-sexp-function)
-		hs-special-modes-alist))))
+  ;; we start from the assertion that `hs-modes-alist' is autoloaded.
+  (unless (assq 'icon-mode hs-modes-alist)
+    (setq hs-modes-alist
+	  (cons '(icon-mode  (start . "\\<procedure\\>") (end . "\\<end\\>")
+                             (forward-fn . icon-forward-sexp-function))
+		hs-modes-alist))))
 
 ;; This is used by indent-for-comment to decide how much to
 ;; indent a comment in Icon code based on its context.
diff --git a/lisp/progmodes/lua-mode.el b/lisp/progmodes/lua-mode.el
index 01d91637cf0..07b3777c988 100644
--- a/lisp/progmodes/lua-mode.el
+++ b/lisp/progmodes/lua-mode.el
@@ -553,12 +553,12 @@ lua-mode
   (add-hook 'flymake-diagnostic-functions #'lua-flymake nil t)
 
   ;; Hide-show setup
-  (unless (assq 'lua-mode hs-special-modes-alist)
-    (add-to-list 'hs-special-modes-alist
+  (unless (assq 'lua-mode hs-modes-alist)
+    (add-to-list 'hs-modes-alist
                  `(lua-mode
-                   ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words) ; Start
-                   ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words) ; End
-                   nil lua-forward-sexp))))
+                   (start . ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words)) ; Start
+                   (end . ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words)) ; End
+                   (forward-fn . lua-forward-sexp)))))
 
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 5a96972caa7..9826edfc054 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -5912,6 +5912,22 @@ python-hideshow-find-next-block
         (beginning-of-line)
         (looking-at regexp)))))
 
+(defun python-ts-hs-adjust-block-end-fn (block-beg)
+  "Python-ts-mode specific `hs-adjust-block-end' function for `hs-minor-mode'.
+
+BLOCK-BEG is the beginning position where the hiding will be performed.
+
+This is only used to properly hide the block when there are not closing
+parens."
+  (unless (save-excursion
+            (goto-char block-beg)
+            (treesit-thing-at
+             (1- (point))
+             '(or "argument_list"
+                  (and anonymous "\\`[](),[{}]\\'")
+                  "string")))
+    (line-end-position)))
+
 
 ;;; Imenu
 
@@ -7339,21 +7355,24 @@ python-base-mode
                       #'python-eldoc-function))))
   (eldoc-add-command-completions "python-indent-dedent-line-backspace")
 
-  ;; TODO: Use tree-sitter to figure out the block in `python-ts-mode'.
-  (dolist (mode '(python-mode python-ts-mode))
-    (add-to-list
-     'hs-special-modes-alist
-     `(,mode
-       ,python-nav-beginning-of-block-regexp
-       ;; Use the empty string as end regexp so it doesn't default to
-       ;; "\\s)".  This way parens at end of defun are properly hidden.
-       ""
-       "#"
-       python-hideshow-forward-sexp-function
-       nil
-       python-nav-beginning-of-block
-       python-hideshow-find-next-block
-       python-info-looking-at-beginning-of-block)))
+  (add-to-list
+   'hs-modes-alist
+   `(python-mode
+     (start . ,python-nav-beginning-of-block-regexp)
+     ;; Use the empty string as end regexp so it doesn't default to
+     ;; "\\s)".  This way parens at end of defun are properly hidden.
+     (end . "")
+     (c-start . "#")
+     (forward-fn . python-hideshow-forward-sexp-function)
+     (find-beg-fn . python-nav-beginning-of-block)
+     (find-next-fn . python-hideshow-find-next-block)
+     (look-start-fn . python-info-looking-at-beginning-of-block)))
+
+  (add-to-list
+   'hs-modes-alist
+   '(python-ts-mode
+     (treesit-things . (or defun sexp))
+     (adjust-end-fn . python-ts-hs-adjust-block-end-fn)))
 
   (setq-local outline-regexp (python-rx (* space) block-start))
   (setq-local outline-level
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 2f5525786e1..81fecec806f 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -4363,12 +4363,12 @@ verilog-mode
   (when (and (boundp 'which-func-modes) (listp which-func-modes))
     (add-to-list 'which-func-modes 'verilog-mode))
   ;; hideshow support
-  (when (boundp 'hs-special-modes-alist)
-    (unless (assq 'verilog-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-            (cons '(verilog-mode "\\<begin\\>" "\\<end\\>" nil
-                                 verilog-forward-sexp-function)
-                  hs-special-modes-alist))))
+  (when (boundp 'hs-modes-alist)
+    (unless (assq 'verilog-mode hs-modes-alist)
+      (setq hs-modes-alist
+            (cons '(verilog-mode (beg . "\\<begin\\>") (end . "\\<end\\>")
+                                 (forward-fn . verilog-forward-sexp-function))
+                  hs-modes-alist))))
 
   (add-hook 'completion-at-point-functions
             #'verilog-completion-at-point nil 'local)
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 593a83ceffa..82e6f41e07e 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -13282,11 +13282,11 @@ vhdl-hs-minor-mode
   (if (not (boundp 'hs-block-start-mdata-select))
       (vhdl-warning-when-idle "Install included `hideshow.el' patch first (see INSTALL file)")
     ;; initialize hideshow
-    (unless (assoc 'vhdl-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-	    (cons (list 'vhdl-mode vhdl-hs-start-regexp nil "--\\( \\|$\\)"
-			'vhdl-hs-forward-sexp-func nil)
-		  hs-special-modes-alist)))
+    (unless (assoc 'vhdl-mode hs-modes-alist)
+      (setq hs-modes-alist
+	    (cons `(vhdl-mode (start . ,vhdl-hs-start-regexp) (c-start . "--\\( \\|$\\)")
+			      (forward-fn . vhdl-hs-forward-sexp-func))
+		  hs-modes-alist)))
     (if (featurep 'xemacs) (make-local-hook 'hs-minor-mode-hook))
     (if vhdl-hide-all-init
 	(add-hook 'hs-minor-mode-hook #'hs-hide-all nil t)
diff --git a/lisp/textmodes/mhtml-mode.el b/lisp/textmodes/mhtml-mode.el
index e1ea73dc9ac..4ab560df6a8 100644
--- a/lisp/textmodes/mhtml-mode.el
+++ b/lisp/textmodes/mhtml-mode.el
@@ -306,7 +306,7 @@ mhtml--flyspell-check-word
         (flyspell-generic-progmode-verify)
       t)))
 
-;; Support for hideshow.el (see `hs-special-modes-alist').
+;; Support for hideshow.el (see `hs-modes-alist').
 (defun mhtml-forward (arg)
   "Move point forward past a structured expression.
 If point is on a tag, move to the end of the tag.
diff --git a/lisp/treesit.el b/lisp/treesit.el
index a8a515c434d..adc72156873 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -4230,7 +4230,7 @@ treesit-outline-level
 
 (defun treesit-hs-block-end ()
   "Tree-sitter implementation of `hs-block-end-regexp'."
-  (let* ((pred 'list)
+  (let* ((pred (bound-and-true-p hs-treesit-things))
          (thing (treesit-thing-at
                  (if (bobp) (point) (1- (point))) pred))
          (end (when thing (treesit-node-end thing)))
@@ -4243,7 +4243,7 @@ treesit-hs-block-end
 
 (defun treesit-hs-find-block-beginning ()
   "Tree-sitter implementation of `hs-find-block-beginning-func'."
-  (let* ((pred 'list)
+  (let* ((pred (bound-and-true-p hs-treesit-things))
          (thing (treesit-thing-at (point) pred))
          (beg (when thing (treesit-node-start thing)))
          (end (when beg (min (1+ beg) (point-max)))))
@@ -4260,17 +4260,18 @@ treesit-hs-find-next-block
           (when comments
             (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
                 'comment "\\`comment\\'")))
-         (pred (if comment-pred (append '(or list) (list comment-pred)) 'list))
+         (hs-things (bound-and-true-p hs-treesit-things))
+         (pred (append `(or ,hs-things) (when comment-pred (list comment-pred))))
          ;; `treesit-navigate-thing' can't find a thing at bobp,
          ;; so use `treesit-thing-at' to match at bobp.
          (current (treesit-thing-at (point) pred))
          (beg (or (and current (eq (point) (treesit-node-start current)) (point))
                   (treesit-navigate-thing (point) 1 'beg pred)))
-         ;; Check if we found a list or a comment
-         (list-thing (when beg (treesit-thing-at beg 'list)))
+         ;; Check if we found a block or a comment
+         (block-thing (when beg (treesit-thing-at beg hs-things)))
          (comment-thing (when beg (treesit-thing-at beg comment-pred)))
          (comment-p (and comment-thing (eq beg (treesit-node-start comment-thing))))
-         (thing (if comment-p comment-thing list-thing))
+         (thing (if comment-p comment-thing block-thing))
          (end (if thing (min (1+ (treesit-node-start thing)) (point-max)))))
     (when (and end (<= end maxp))
       (goto-char end)
@@ -4282,7 +4283,7 @@ treesit-hs-find-next-block
 
 (defun treesit-hs-looking-at-block-start-p ()
   "Tree-sitter implementation of `hs-looking-at-block-start-p-func'."
-  (let* ((pred 'list)
+  (let* ((pred (bound-and-true-p hs-treesit-things))
          (thing (treesit-thing-at (point) pred))
          (beg (when thing (treesit-node-start thing)))
          (end (min (1+ (point)) (point-max))))
-- 
2.51.0


--=-=-=
Content-Type: text/plain


-- 
- E.G via Gnus and Org.

--=-=-=--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 28 Oct 2025 12:51:19 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Oct 28 08:51:19 2025
Received: from localhost ([127.0.0.1]:52511 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vDjAU-0004AR-In
	for submit <at> debbugs.gnu.org; Tue, 28 Oct 2025 08:51:19 -0400
Received: from eggs.gnu.org ([2001:470:142:3::10]:47152)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <eliz@HIDDEN>) id 1vDjAK-0004A2-Ud
 for 79671 <at> debbugs.gnu.org; Tue, 28 Oct 2025 08:51:13 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <eliz@HIDDEN>)
 id 1vDjAF-0007CR-18; Tue, 28 Oct 2025 08:51:03 -0400
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org;
 s=fencepost-gnu-org; h=MIME-version:References:Subject:In-Reply-To:To:From:
 Date; bh=httiBy21VF1SkoFXS28nSkpaWfXAPC2C9P782DyOTWk=; b=E6oVi6Fq+4i1CpGH4la6
 LAeRMVcXHrQHPMLbSvc+EvDqpmagzazLC+2T0bu7yP0Xnij8t72akl3CLF/5IJJ8/wr2lHNQFQnlr
 TpXhsxuASN4i0cLcPhWysGKmv97S0B3VYpM6cJCG8hjRZs5E6uOM2MZCDrhtEPj6GJ1AYWdUs7C8h
 wn0T9EWZ53o5nmHcrF3IkQKEX9VeNOVZuBfs9oa+souWWSkO8E9rc4adcEiSq/GmND15shllSrVC1
 7eAbV8gRENhnGnFmrvB3a/qBN6sUgZGc/ZHiy5vgOnaynZAYd9gHQ+2HhovxdxDk7nv625zmgQ64V
 ESjZ9RqlmKFmZw==;
Date: Tue, 28 Oct 2025 14:50:59 +0200
Message-Id: <86h5vjp4uk.fsf@HIDDEN>
From: Eli Zaretskii <eliz@HIDDEN>
To: Elijah Gabe =?utf-8?Q?P=C3=A9rez?= <eg642616@HIDDEN>
In-Reply-To: <877bwgqhte.fsf_-_@HIDDEN> (message from Elijah Gabe
 =?utf-8?Q?P=C3=A9rez?= on Mon, 27 Oct 2025 13:13:17 -0600)
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
 <877bwgqhte.fsf_-_@HIDDEN>
MIME-version: 1.0
Content-type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org, juri@HIDDEN
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

> Cc: 79671 <at> debbugs.gnu.org
> From: Elijah Gabe Pérez <eg642616@HIDDEN>
> Date: Mon, 27 Oct 2025 13:13:17 -0600
> 
> +TREESIT-THINGS is a thing defined in `treesit-thing-settings' to
> +determine if current block at point is valid, see
> +`treesit-thing-settings' to get more information about.
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"for more information"

> +All the elements supports mode hierarchy.  If any of the elements is
                    ^^^^^^^^
"support", plural

> +left nil or omitted, hideshow searches for a value defined in some
> +parent mode in this alist, if no value is found, it tries to guess the
                            ^
Please replace that comma with semi-colon.

> +(defvar-local hs-adjust-block-end nil
> +  "Function used to tweak the block end.
> +This is useful to ensure some characters such as parenthesis or curly
> +braces get properly hidden in python-like modes.
> +
> +It is called with 1 argument which is the hiding beginning position.
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"which is the beginning position of the block"

> +It should return the position from where the hiding ends.")

"It should return the last position to hide" (or did you mean "the
first position after the block that should not be hidden"?).

> +(defun python-ts-adjust-block-end-fn (block-beg)
> +  "Python-ts-mode specific `hs-adjust-block-end' function for `hs-minor-mode'.
> +
> +BLOCK-BEG is the beginning position where the hiding will be performed.
> +
> +This is only used to ensure the block end position in function
> +definitions and parens."

I don't understand the last sentence.  What does this ensure?

Thanks.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 27 Oct 2025 19:13:40 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Oct 27 15:13:40 2025
Received: from localhost ([127.0.0.1]:50146 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vDSew-0003rX-Jl
	for submit <at> debbugs.gnu.org; Mon, 27 Oct 2025 15:13:40 -0400
Received: from mail-ot1-x343.google.com ([2607:f8b0:4864:20::343]:57497)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vDSeo-0003r9-US
 for 79671 <at> debbugs.gnu.org; Mon, 27 Oct 2025 15:13:33 -0400
Received: by mail-ot1-x343.google.com with SMTP id
 46e09a7af769-7c2878bdf27so3301673a34.2
 for <79671 <at> debbugs.gnu.org>; Mon, 27 Oct 2025 12:13:30 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761592404; x=1762197204; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=RGBfFr0WPv4NjHUoEeLQyj7SeAzbxZ/nRULBoOInTGw=;
 b=YbdOcPiQNRwKS6QxIwI8XteMQks9Qk5/Nk0ksU/mAkTSGBaTEzYOf1UUz259Yg1ViI
 zKEfO/h4AQoPlfGXNckuSPtIw0ErPwvo02RLTJZu6se5AqeJoocjK5sE5SkYhOJgiMyq
 bMqnqeTrTZKRRVqm2Hd/YzBW0YKuU6dg2GmYbqO74MGuomu7oRsB0Bbo0HApIbbvzROd
 jjeMbBZRtfQAxVpEdFENHGeWuDf/ySqaTo6lPb4DmlUr35a+c8gcW4YeRUdBuXIE877Y
 RKREAcVeULCUGGWEiy/AhajTmcp+lCHmxXFpytg3Itqot4g9QYEWTzQ3MSxlFTA1hT8D
 oAnA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761592404; x=1762197204;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=RGBfFr0WPv4NjHUoEeLQyj7SeAzbxZ/nRULBoOInTGw=;
 b=Ega4NXSQ7zmiDzAfuDTTUORGWyvkI46QcypkeotdWtFGT+qOcKigT2r9huUx9PlY7T
 S4bbO6yZ4LLXGBY3uwFo8RhIuofHM14Dn5HEqQ15QYiGbvLcKkdR1aol7CsddMNUxWow
 IBfBMD6P9aFuR0KrYDcBxFZI8sU8s0YUqXr79XbTL8qgYyNljxYgHf5kTf77J1onChs3
 yT2iMXHRUT3bhpLml2Z05btcj4JiB6/6tAauoQfsXI1VLR/oHW5rLVIbOaqRoC9b56fV
 GMkyrF5qyPKqvbWkkP1nYKhoNqXjIgaSvzS4J5fsSTkFljYh85HDTPY8TqxRSUpCCxBg
 ijcw==
X-Gm-Message-State: AOJu0YxG4tPWkXjich2gJ6Mesu+e7klWZNG/Rggm00ViPiIa/qcG4LqC
 13OQGomRL9wlmL6aAxCz0NEw/Ked61BBV8n/1THeupr9/0IHPCLW41/sgHDd0Cvw
X-Gm-Gg: ASbGnctpVHs3mHB+H1z36xZdeW7X9lrplOfprhyk6QjrcQmmHtCzmj0IicNi45cJ5h8
 a6TL4XGQKT31NLz57e9jEOpi9NsxlNv2NAytYrJ+GnsLyj2DXC86aGpjsR+TtPHN3sTB7otMf7k
 WwpfKf1ArWrcjMPuXZfDRlI/hiWMiCpY7gn/AdbtVpQhnoIF3ySUqGSXLN4YT9Uu+DWi+Rj2YWp
 coTOszo0jomVjJ2rOnQOdX8dF1qULpEJmFHc1yBN/lYNjLbfLyw5QQt1IvprUYBJikthJngCPWK
 XvbdQE2KDuY0xXLmOVoSpvOR+ci3Yy3BlrEOFtKibcUrp8pKEcq8beMwzm/lRR/aZ9+B+/zJ3c3
 kLY7fK8ra8480PJ/pOU7o5PWT35Ry/Oiv/3ZWlHXhoWDseKUscZf0NiGb7a/wnLK1GkKQZeWb3J
 3Mr/Xf
X-Google-Smtp-Source: AGHT+IEQSD1u1YVJk+8gU/gycTeOS7JZSla6q8c5z3XPoxODvPAbd8oyZR+qSTylgnGAI0Gk4KJUug==
X-Received: by 2002:a05:6808:3508:b0:44d:b213:169 with SMTP id
 5614622812f47-44f6baedde1mr372685b6e.37.1761592403643; 
 Mon, 27 Oct 2025 12:13:23 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 006d021491bc7-654ef2726absm2044804eaf.3.2025.10.27.12.13.19
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Mon, 27 Oct 2025 12:13:22 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Juri Linkov <juri@HIDDEN>
Subject: Re: bug#79671: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
In-Reply-To: <87zf9cs0zh.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN> <87zf9cs0zh.fsf@HIDDEN>
Date: Mon, 27 Oct 2025 13:13:17 -0600
Message-ID: <877bwgqhte.fsf_-_@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

--=-=-=
Content-Type: text/plain

Juri Linkov <juri@HIDDEN> writes:

> This is just a stylistic question, what I proposed to do
> is to avoid such guards:
>
>   (when (bound-and-true-p hs-treesit-things)

Oh i see, I've applied your suggestion.

>> Here is the updated patch, I'm not sure if this change in
>> `hs-special-modes-alist` should be announced in NEWS, since this is a
>> drastic change:
>
> Indeed, the most important changes should be announced in NEWS,
> and maybe also briefly mentioned in (info "(emacs) Hideshow")
> where currently 'hs-special-modes-alist' is only indexed
> without any occurrences in the text.

Fine, I have updated the patch, it should be ready now.


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow-Rewrite-hs-special-modes-alist.patch

From 6cdad5d1691530950567eb55efebb5c2a9e089ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Mon, 13 Oct 2025 18:45:21 -0600
Subject: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'

Rewrite the format in 'hs-special-modes-alist' to make easier to
exclude some values, add support for settings inheritance
according to current major mode and parents, and support string
hiding for lisp modes.

Bug#79671

* lisp/progmodes/hideshow.el (hs-modes-alist): New variable.
(hs-special-modes-alist): Mark as obsolete.
(hs-forward-sexp-func, hs-adjust-block-beginning)
(hs-find-block-beginning-func, hs-find-next-block-func)
(hs-looking-at-block-start-p-func): Set default values to nil.
(hs-adjust-block-end, hs-treesit-things): New buffer-local
variables.
(hs-block-positions): Minor updates.
(hs--get-mode-value): New function.
(hs-grok-mode-type): Rewrite.
* lisp/progmodes/f90.el (hs-special-modes-alist):
* lisp/progmodes/fortran.el (hs-special-modes-alist):
* lisp/progmodes/icon.el (icon-mode):
* lisp/progmodes/lua-mode.el (lua-mode):
* lisp/progmodes/python.el (python-base-mode):
* lisp/progmodes/verilog-mode.el (verilog-mode):
* lisp/progmodes/vhdl-mode.el (vhdl-hs-minor-mode): Rewrite
settings.
* lisp/progmodes/python.el (python-ts-adjust-block-end-fn): New
function.
* lisp/treesit.el (treesit-hs-block-end)
(treesit-hs-find-block-beginning, treesit-hs-find-next-block)
(treesit-hs-looking-at-block-start-p): Minor updates.
* doc/emacs/programs.texi (Hideshow):
* etc/NEWS: Document changes.
---
 doc/emacs/programs.texi        |   5 +-
 etc/NEWS                       |   6 ++
 lisp/progmodes/f90.el          |  12 +--
 lisp/progmodes/fortran.el      |  12 +--
 lisp/progmodes/hideshow.el     | 153 +++++++++++++++++++++++----------
 lisp/progmodes/icon.el         |  12 +--
 lisp/progmodes/lua-mode.el     |  10 +--
 lisp/progmodes/python.el       |  37 ++++++--
 lisp/progmodes/verilog-mode.el |  12 +--
 lisp/progmodes/vhdl-mode.el    |  10 +--
 lisp/textmodes/mhtml-mode.el   |   2 +-
 lisp/treesit.el                |  15 ++--
 12 files changed, 189 insertions(+), 97 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index f42f40fa28f..12bde32be05 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1735,7 +1735,7 @@ Hideshow
 @vindex hs-indicator-maximum-buffer-size
 @vindex hs-isearch-open
 @vindex hs-hide-block-behavior
-@vindex hs-special-modes-alist
+@vindex hs-modes-alist
   These variables can be used to customize Hideshow mode:
 
 @table @code
@@ -1782,6 +1782,9 @@ Hideshow
 nor comments).  The default value is @code{code}.
 @end table
 
+All necessary settings for each mode can be found in the variable
+@code{hs-modes-alist}.
+
 @node Symbol Completion
 @section Completion for Symbol Names
 @cindex completion (symbol names)
diff --git a/etc/NEWS b/etc/NEWS
index f61825f531b..f5dfa24d2b9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1069,6 +1069,12 @@ should hide a block.  If set to 'after-bol', hide the innermost block to
 which the current line belongs.  If set to 'after-cursor', hide the block
 after cursor position.  By default this is set to 'after-bol'.
 
++++
+*** The variable 'hs-special-modes-alist' is now obsolete.
+Use the new variable 'hs-modes-alist' instead, which supports mode
+hierarchy for each value.
+
+
 ** C-ts mode
 
 +++
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index 96626600d55..c3158069dcd 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -930,7 +930,7 @@ f90-end-block-re
                         "block" "critical") t)
           "\\_>")
   "Regexp matching the end of an F90 \"block\", from the line start.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
 ;; Ignore the fact that FUNCTION, SUBROUTINE, WHERE, FORALL have a
 ;; following "(".  DO, CASE, IF can have labels.
@@ -966,12 +966,12 @@ f90-start-block-re
   "Regexp matching the start of an F90 \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
-;; hs-special-modes-alist is autoloaded.
-(add-to-list 'hs-special-modes-alist
-             `(f90-mode ,f90-start-block-re ,f90-end-block-re
-                        "!" f90-end-of-block nil))
+;; hs-modes-alist is autoloaded.
+(add-to-list 'hs-modes-alist
+             `(f90-mode (start . ,f90-start-block-re) (end . ,f90-end-block-re)
+                        (c-start . "!") (forward-fn . f90-end-of-block)))
 
 
 ;; Imenu support.
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index d1f14fdf8fe..6eb75af01a3 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -549,7 +549,7 @@ fortran-end-block-re
           "\\|!\\|$\\)")
   "Regexp matching the end of a Fortran \"block\", from the line start.
 Note that only ENDDO is handled for the end of a DO-loop.  Used
-in the Fortran entry in `hs-special-modes-alist'.")
+in the Fortran entry in `hs-modes-alist'.")
 
 (defconst fortran-start-block-re
   (concat
@@ -582,11 +582,11 @@ fortran-start-block-re
   "Regexp matching the start of a Fortran \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the Fortran entry in `hs-special-modes-alist'.")
+Used in the Fortran entry in `hs-modes-alist'.")
 
-(add-to-list 'hs-special-modes-alist
-             `(fortran-mode ,fortran-start-block-re ,fortran-end-block-re
-                            "^[cC*!]" fortran-end-of-block nil))
+(add-to-list 'hs-modes-alist
+             `(fortran-mode (start . ,fortran-start-block-re) (end . ,fortran-end-block-re)
+                            (c-start . "^[cC*!]") (forward-fn . fortran-end-of-block)))
 
 
 (defvar fortran-mode-syntax-table
@@ -1247,7 +1247,7 @@ fortran-looking-at-if-then
           (goto-char i)
           (= (line-beginning-position) p)))))
 
-;; Used in hs-special-modes-alist.
+;; Used in hs-modes-alist.
 (defun fortran-end-of-block (&optional num)
   "Move point forward to the end of the current code block.
 With optional argument NUM, go forward that many balanced blocks.
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index 6158253ee53..88a349afe94 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -370,30 +370,41 @@ hs-indicator-show
   :version "31.1")
 
 ;;;###autoload
-(defvar hs-special-modes-alist
-  ;; FIXME: Currently the check is made via
-  ;; (assoc major-mode hs-special-modes-alist) so it doesn't pay attention
-  ;; to the mode hierarchy.
-  '((c-mode "{" "}" "/[*/]" nil nil)
-    (c-ts-mode "{" "}" "/[*/]" nil nil)
-    (c++-mode "{" "}" "/[*/]" nil nil)
-    (c++-ts-mode "{" "}" "/[*/]" nil nil)
-    (bibtex-mode ("@\\S(*\\(\\s(\\)" 1))
-    (java-mode "{" "}" "/[*/]" nil nil)
-    (java-ts-mode "{" "}" "/[*/]" nil nil)
-    (js-mode "{" "}" "/[*/]" nil)
-    (js-ts-mode "{" "}" "/[*/]" nil)
-    (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil)
+(defvar hs-special-modes-alist nil)
+(make-obsolete-variable 'hs-special-modes-alist 'hs-modes-alist "31.1")
+
+;;;###autoload
+(defvar hs-modes-alist
+  '((c-mode    (start . "{") (end . "}") (c-start . "/[*/]"))
+    (c++-mode  (start . "{") (end . "}") (c-start . "/[*/]"))
+    (java-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (bibtex-mode  (start . ("@\\S(*\\(\\s(\\)" 1)))
+    (js-base-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (sgml-mode (start . "<[^/>]*?") (end . "</[^/>]*[^/]>")
+               (c-start . "<!--") (forward-fn . sgml-skip-tag-forward))
+    (html-mode (start . "{\\|<[^/>]*?") (end . "}\\|</[^/>]*[^/]>")
+               (forward-fn . forward-sexp))
+    (mhtml-mode (forward-fn . mhtml-forward))
+    (lisp-data-mode (start . "\\s(\\|\"") (end . "\\s)\\|\""))
     ;; Add more support here.
     )
   "Alist for initializing the hideshow variables for different modes.
-Each element has the form
-  (MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC
-   FIND-BLOCK-BEGINNING-FUNC FIND-NEXT-BLOCK-FUNC
-   LOOKING-AT-BLOCK-START-P-FUNC).
+Each element is an alist with any of the cons-cells forms:
+ (MODE &optional
+       (start . START)
+       (end . END)
+       (c-start . COMMENT-START)
+       (forward-fn . FORWARD-SEXP-FUNC)
+       (adjust-beg-fn . ADJUST-BEG-FUNC)
+       (adjust-end-fn . ADJUST-END-FUNC)
+       (find-beg-fn . FIND-BLOCK-BEGINNING-FUNC)
+       (find-next-fn . FIND-NEXT-BLOCK-FUNC)
+       (look-start-fn . LOOKING-AT-BLOCK-START-P-FUNC)
+       (treesit-things . TREESIT-THINGS))
 
 If non-nil, hideshow will use these values as regexps to define blocks
-and comments, respectively for major mode MODE.
+and comments, respectively for major mode MODE or current major mode
+parents.
 
 START, END and COMMENT-START are regular expressions.  A block is
 defined as text surrounded by START and END.
@@ -403,7 +414,7 @@ hs-special-modes-alist
 MDATA-SELECTOR an integer that specifies which sub-match is the proper
 place to adjust point, before calling `hs-forward-sexp-func'.  Point
 is adjusted to the beginning of the specified match.  For example,
-see the `hs-special-modes-alist' entry for `bibtex-mode'.
+see the `hs-modes-alist' entry for `bibtex-mode'.
 
 For some major modes, `forward-sexp' does not work properly.  In those
 cases, FORWARD-SEXP-FUNC specifies another function to use instead.
@@ -411,6 +422,9 @@ hs-special-modes-alist
 See the documentation for `hs-adjust-block-beginning' to see what is the
 use of ADJUST-BEG-FUNC.
 
+See the documentation for `hs-adjust-block-end' to see what is the
+use of ADJUST-END-FUNC.
+
 See the documentation for `hs-find-block-beginning-func' to see
 what is the use of FIND-BLOCK-BEGINNING-FUNC.
 
@@ -420,7 +434,13 @@ hs-special-modes-alist
 See the documentation for `hs-looking-at-block-start-p-func' to
 see what is the use of LOOKING-AT-BLOCK-START-P-FUNC.
 
-If any of the elements is left nil or omitted, hideshow tries to guess
+TREESIT-THINGS is a thing defined in `treesit-thing-settings' to
+determine if current block at point is valid, see
+`treesit-thing-settings' to get more information about.
+
+All the elements supports mode hierarchy.  If any of the elements is
+left nil or omitted, hideshow searches for a value defined in some
+parent mode in this alist, if no value is found, it tries to guess the
 appropriate values.  The regexps should not contain leading or trailing
 whitespace.  Case does not matter.")
 
@@ -548,7 +568,7 @@ hs-block-start-mdata-select
 (defvar-local hs-block-end-regexp nil
   "Regexp for end of block.")
 
-(defvar-local hs-forward-sexp-func #'forward-sexp
+(defvar-local hs-forward-sexp-func nil
   "Function used to do a `forward-sexp'.
 Should change for Algol-ish modes.  For single-character block
 delimiters -- ie, the syntax table regexp for the character is
@@ -556,7 +576,7 @@ hs-forward-sexp-func
 `forward-sexp'.  For other modes such as simula, a more specialized
 function is necessary.")
 
-(defvar-local hs-adjust-block-beginning #'identity
+(defvar-local hs-adjust-block-beginning nil
   "Function used to tweak the block beginning.
 The block is hidden from the position returned by this function,
 as opposed to hiding it from the position returned when searching
@@ -576,7 +596,16 @@ hs-adjust-block-beginning
 
 See `hs-c-like-adjust-block-beginning' for an example of using this.")
 
-(defvar-local hs-find-block-beginning-func #'hs-find-block-beginning
+(defvar-local hs-adjust-block-end nil
+  "Function used to tweak the block end.
+This is useful to ensure some characters such as parenthesis or curly
+braces get properly hidden in python-like modes.
+
+It is called with 1 argument which is the hiding beginning position.
+
+It should return the position from where the hiding ends.")
+
+(defvar-local hs-find-block-beginning-func nil
   "Function used to do `hs-find-block-beginning'.
 It should reposition point at the beginning of the current block
 and return point, or nil if original point was not in a block.
@@ -585,7 +614,7 @@ hs-find-block-beginning-func
 Python, where regexp search and `syntax-ppss' check is not enough
 to find the beginning of the current block.")
 
-(defvar-local hs-find-next-block-func #'hs-find-next-block
+(defvar-local hs-find-next-block-func nil
   "Function used to do `hs-find-next-block'.
 It should reposition point at next block start.
 
@@ -601,7 +630,7 @@ hs-find-next-block-func
 Python, where regexp search is not enough to find the beginning
 of the next block.")
 
-(defvar-local hs-looking-at-block-start-p-func #'hs-looking-at-block-start-p
+(defvar-local hs-looking-at-block-start-p-func nil
   "Function used to do `hs-looking-at-block-start-p'.
 It should return non-nil if the point is at the block start.
 
@@ -612,6 +641,11 @@ hs-looking-at-block-start-p-func
 (defvar-local hs-inside-comment-p-func nil
   "Function used to check if point is inside a comment.")
 
+(defvar-local hs-treesit-things nil
+  "Treesit things to check if point is at a valid block.
+The value should be a thing defined in `treesit-thing-settings' for the
+current buffer's major mode.")
+
 (defvar hs-headline nil
   "Text of the line where a hidden block begins, set during isearch.
 You can display this in the mode line by adding the symbol `hs-headline'
@@ -703,8 +737,7 @@ hs-block-positions
           ;; `block-start' is the point at the end of the block
           ;; beginning, which may need to be adjusted
           (save-excursion
-            (goto-char (funcall (or hs-adjust-block-beginning #'identity)
-                                header-end))
+            (goto-char (funcall hs-adjust-block-beginning header-end))
             (setq block-beg (line-end-position)))
           ;; `block-end' is the point at the end of the block
           (hs-forward-sexp mdata 1)
@@ -716,7 +749,8 @@ hs-block-positions
                        (funcall hs-block-end-regexp)
                        (match-beginning 0))
                       (t (point))))
-          (cons block-beg block-end))))))
+          (cons block-beg
+                (or (funcall hs-adjust-block-end block-beg) block-end)))))))
 
 (defun hs--make-indicators-overlays (beg)
   "Helper function to make the indicators overlays."
@@ -987,16 +1021,31 @@ hs-inside-comment-p--default
           (when (>= (point) q)
             (list (and hideable p) (point))))))))
 
+(defun hs--get-mode-value (value &optional old-nth)
+  "Get VALUE for current major mode in `hs-modes-alist'.
+OLD-NTH is only used for backward compatibility with
+`hs-special-modes-alist'."
+  (if-let* (old-nth
+            (old-lookup (assoc major-mode hs-special-modes-alist)))
+      (nth old-nth old-lookup)
+    (catch 'hs-grok-exit
+      (dolist (modes (get major-mode 'derived-mode--all-parents))
+        ;; If we cannot find VALUE in current MODES, try to find it in
+        ;; the next mode in MODES
+        (if-let* ((list (assoc modes hs-modes-alist))
+                  (elm (alist-get value list)))
+            (throw 'hs-grok-exit elm))))))
+
 (defun hs-grok-mode-type ()
   "Set up hideshow variables for new buffers.
-If `hs-special-modes-alist' has information associated with the
+If `hs-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 (bound-and-true-p comment-start)
            (bound-and-true-p comment-end))
-      (let* ((lookup (assoc major-mode hs-special-modes-alist))
-             (start-elem (or (nth 1 lookup) "\\s(")))
+      (let ((start-elem (or (hs--get-mode-value 'start 1) "\\s(")))
+
         (if (listp start-elem)
             ;; handle (START-REGEXP MDATA-SELECT)
             (setq hs-block-start-regexp (car start-elem)
@@ -1004,23 +1053,39 @@ hs-grok-mode-type
           ;; 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)
+
+        (setq hs-block-end-regexp (or hs-block-end-regexp
+                                      (hs--get-mode-value 'end 2)
+                                      "\\s)")
+              hs-c-start-regexp (or hs-c-start-regexp
+                                    (hs--get-mode-value 'c-start 3)
                                     (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 (or (nth 5 lookup) #'identity)
-              hs-find-block-beginning-func (or (nth 6 lookup)
+              hs-forward-sexp-func (or hs-forward-sexp-func
+                                       (hs--get-mode-value 'forward-fn 4)
+                                       #'forward-sexp)
+              hs-adjust-block-beginning (or hs-adjust-block-beginning
+                                            (hs--get-mode-value 'adjust-fn 5)
+                                            #'identity)
+              hs-adjust-block-end (or hs-adjust-block-end
+                                      (hs--get-mode-value 'adjust-end-fn 5)
+                                      #'ignore)
+              hs-find-block-beginning-func (or hs-find-block-beginning-func
+                                               (hs--get-mode-value 'find-beg-fn 6)
                                                #'hs-find-block-beginning)
-              hs-find-next-block-func (or (nth 7 lookup)
+              hs-find-next-block-func (or hs-find-next-block-func
+                                          (hs--get-mode-value 'find-next-fn 7)
                                           #'hs-find-next-block)
-              hs-looking-at-block-start-p-func
-              (or (nth 8 lookup)
-                  #'hs-looking-at-block-start-p)))
+              hs-looking-at-block-start-p-func (or hs-looking-at-block-start-p-func
+                                                   (hs--get-mode-value 'look-start-fn 8)
+                                                   #'hs-looking-at-block-start-p)
+              hs-treesit-things (or hs-treesit-things
+                                    (hs--get-mode-value 'treesit-things)
+                                    'list)))
     (setq hs-minor-mode nil)
     (error "%s Mode doesn't support Hideshow Minor Mode"
            (format-mode-line mode-name))))
@@ -1341,10 +1406,8 @@ hs-minor-mode
   (setq hs-headline nil)
   (if hs-minor-mode
       (progn
-        ;; Use such heuristics that if one buffer-local variable
-        ;; is already defined, don't overwrite other variables too.
-        (unless (buffer-local-value 'hs-inside-comment-p-func (current-buffer))
-          (hs-grok-mode-type))
+        ;; Set the variables according to `hs-modes-alist'.
+        (hs-grok-mode-type)
         ;; Turn off this mode if we change major modes.
         (add-hook 'change-major-mode-hook
                   #'turn-off-hideshow
diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el
index dee57956ce7..2a5172609d9 100644
--- a/lisp/progmodes/icon.el
+++ b/lisp/progmodes/icon.el
@@ -167,12 +167,12 @@ icon-mode
   ;; imenu support
   (setq-local imenu-generic-expression icon-imenu-generic-expression)
   ;; hideshow support
-  ;; we start from the assertion that `hs-special-modes-alist' is autoloaded.
-  (unless (assq 'icon-mode hs-special-modes-alist)
-    (setq hs-special-modes-alist
-	  (cons '(icon-mode  "\\<procedure\\>" "\\<end\\>" nil
-			     icon-forward-sexp-function)
-		hs-special-modes-alist))))
+  ;; we start from the assertion that `hs-modes-alist' is autoloaded.
+  (unless (assq 'icon-mode hs-modes-alist)
+    (setq hs-modes-alist
+	  (cons '(icon-mode  (start . "\\<procedure\\>") (end . "\\<end\\>")
+                             (forward-fn . icon-forward-sexp-function))
+		hs-modes-alist))))
 
 ;; This is used by indent-for-comment to decide how much to
 ;; indent a comment in Icon code based on its context.
diff --git a/lisp/progmodes/lua-mode.el b/lisp/progmodes/lua-mode.el
index 01d91637cf0..07b3777c988 100644
--- a/lisp/progmodes/lua-mode.el
+++ b/lisp/progmodes/lua-mode.el
@@ -553,12 +553,12 @@ lua-mode
   (add-hook 'flymake-diagnostic-functions #'lua-flymake nil t)
 
   ;; Hide-show setup
-  (unless (assq 'lua-mode hs-special-modes-alist)
-    (add-to-list 'hs-special-modes-alist
+  (unless (assq 'lua-mode hs-modes-alist)
+    (add-to-list 'hs-modes-alist
                  `(lua-mode
-                   ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words) ; Start
-                   ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words) ; End
-                   nil lua-forward-sexp))))
+                   (start . ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words)) ; Start
+                   (end . ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words)) ; End
+                   (forward-fn . lua-forward-sexp)))))
 
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 5a96972caa7..e1df123d172 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -5912,6 +5912,20 @@ python-hideshow-find-next-block
         (beginning-of-line)
         (looking-at regexp)))))
 
+(defun python-ts-adjust-block-end-fn (block-beg)
+  "Python-ts-mode specific `hs-adjust-block-end' function for `hs-minor-mode'.
+
+BLOCK-BEG is the beginning position where the hiding will be performed.
+
+This is only used to ensure the block end position in function
+definitions and parens."
+  (unless (save-excursion
+            (goto-char block-beg)
+            (treesit-thing-at
+             (if (bobp) (point) (1- (point)))
+             '(or "argument_list" (and anonymous "\\`[](),[{}]\\'"))))
+    (line-end-position)))
+
 
 ;;; Imenu
 
@@ -7342,18 +7356,23 @@ python-base-mode
   ;; TODO: Use tree-sitter to figure out the block in `python-ts-mode'.
   (dolist (mode '(python-mode python-ts-mode))
     (add-to-list
-     'hs-special-modes-alist
+     'hs-modes-alist
      `(,mode
-       ,python-nav-beginning-of-block-regexp
+       (start . ,python-nav-beginning-of-block-regexp)
        ;; Use the empty string as end regexp so it doesn't default to
        ;; "\\s)".  This way parens at end of defun are properly hidden.
-       ""
-       "#"
-       python-hideshow-forward-sexp-function
-       nil
-       python-nav-beginning-of-block
-       python-hideshow-find-next-block
-       python-info-looking-at-beginning-of-block)))
+       (end . "")
+       (c-start . "#")
+       (forward-fn . python-hideshow-forward-sexp-function)
+       (find-beg-fn . python-nav-beginning-of-block)
+       (find-next-fn . python-hideshow-find-next-block)
+       (look-start-fn . python-info-looking-at-beginning-of-block)
+       (treesit-things . (or defun sexp)))))
+
+  (add-to-list
+   'hs-modes-alist
+   '(python-ts-mode
+     (adjust-end-fn . python-ts-adjust-block-end-fn)))
 
   (setq-local outline-regexp (python-rx (* space) block-start))
   (setq-local outline-level
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 2f5525786e1..81fecec806f 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -4363,12 +4363,12 @@ verilog-mode
   (when (and (boundp 'which-func-modes) (listp which-func-modes))
     (add-to-list 'which-func-modes 'verilog-mode))
   ;; hideshow support
-  (when (boundp 'hs-special-modes-alist)
-    (unless (assq 'verilog-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-            (cons '(verilog-mode "\\<begin\\>" "\\<end\\>" nil
-                                 verilog-forward-sexp-function)
-                  hs-special-modes-alist))))
+  (when (boundp 'hs-modes-alist)
+    (unless (assq 'verilog-mode hs-modes-alist)
+      (setq hs-modes-alist
+            (cons '(verilog-mode (beg . "\\<begin\\>") (end . "\\<end\\>")
+                                 (forward-fn . verilog-forward-sexp-function))
+                  hs-modes-alist))))
 
   (add-hook 'completion-at-point-functions
             #'verilog-completion-at-point nil 'local)
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 593a83ceffa..82e6f41e07e 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -13282,11 +13282,11 @@ vhdl-hs-minor-mode
   (if (not (boundp 'hs-block-start-mdata-select))
       (vhdl-warning-when-idle "Install included `hideshow.el' patch first (see INSTALL file)")
     ;; initialize hideshow
-    (unless (assoc 'vhdl-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-	    (cons (list 'vhdl-mode vhdl-hs-start-regexp nil "--\\( \\|$\\)"
-			'vhdl-hs-forward-sexp-func nil)
-		  hs-special-modes-alist)))
+    (unless (assoc 'vhdl-mode hs-modes-alist)
+      (setq hs-modes-alist
+	    (cons `(vhdl-mode (start . ,vhdl-hs-start-regexp) (c-start . "--\\( \\|$\\)")
+			      (forward-fn . vhdl-hs-forward-sexp-func))
+		  hs-modes-alist)))
     (if (featurep 'xemacs) (make-local-hook 'hs-minor-mode-hook))
     (if vhdl-hide-all-init
 	(add-hook 'hs-minor-mode-hook #'hs-hide-all nil t)
diff --git a/lisp/textmodes/mhtml-mode.el b/lisp/textmodes/mhtml-mode.el
index e1ea73dc9ac..4ab560df6a8 100644
--- a/lisp/textmodes/mhtml-mode.el
+++ b/lisp/textmodes/mhtml-mode.el
@@ -306,7 +306,7 @@ mhtml--flyspell-check-word
         (flyspell-generic-progmode-verify)
       t)))
 
-;; Support for hideshow.el (see `hs-special-modes-alist').
+;; Support for hideshow.el (see `hs-modes-alist').
 (defun mhtml-forward (arg)
   "Move point forward past a structured expression.
 If point is on a tag, move to the end of the tag.
diff --git a/lisp/treesit.el b/lisp/treesit.el
index a8a515c434d..adc72156873 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -4230,7 +4230,7 @@ treesit-outline-level
 
 (defun treesit-hs-block-end ()
   "Tree-sitter implementation of `hs-block-end-regexp'."
-  (let* ((pred 'list)
+  (let* ((pred (bound-and-true-p hs-treesit-things))
          (thing (treesit-thing-at
                  (if (bobp) (point) (1- (point))) pred))
          (end (when thing (treesit-node-end thing)))
@@ -4243,7 +4243,7 @@ treesit-hs-block-end
 
 (defun treesit-hs-find-block-beginning ()
   "Tree-sitter implementation of `hs-find-block-beginning-func'."
-  (let* ((pred 'list)
+  (let* ((pred (bound-and-true-p hs-treesit-things))
          (thing (treesit-thing-at (point) pred))
          (beg (when thing (treesit-node-start thing)))
          (end (when beg (min (1+ beg) (point-max)))))
@@ -4260,17 +4260,18 @@ treesit-hs-find-next-block
           (when comments
             (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
                 'comment "\\`comment\\'")))
-         (pred (if comment-pred (append '(or list) (list comment-pred)) 'list))
+         (hs-things (bound-and-true-p hs-treesit-things))
+         (pred (append `(or ,hs-things) (when comment-pred (list comment-pred))))
          ;; `treesit-navigate-thing' can't find a thing at bobp,
          ;; so use `treesit-thing-at' to match at bobp.
          (current (treesit-thing-at (point) pred))
          (beg (or (and current (eq (point) (treesit-node-start current)) (point))
                   (treesit-navigate-thing (point) 1 'beg pred)))
-         ;; Check if we found a list or a comment
-         (list-thing (when beg (treesit-thing-at beg 'list)))
+         ;; Check if we found a block or a comment
+         (block-thing (when beg (treesit-thing-at beg hs-things)))
          (comment-thing (when beg (treesit-thing-at beg comment-pred)))
          (comment-p (and comment-thing (eq beg (treesit-node-start comment-thing))))
-         (thing (if comment-p comment-thing list-thing))
+         (thing (if comment-p comment-thing block-thing))
          (end (if thing (min (1+ (treesit-node-start thing)) (point-max)))))
     (when (and end (<= end maxp))
       (goto-char end)
@@ -4282,7 +4283,7 @@ treesit-hs-find-next-block
 
 (defun treesit-hs-looking-at-block-start-p ()
   "Tree-sitter implementation of `hs-looking-at-block-start-p-func'."
-  (let* ((pred 'list)
+  (let* ((pred (bound-and-true-p hs-treesit-things))
          (thing (treesit-thing-at (point) pred))
          (beg (when thing (treesit-node-start thing)))
          (end (min (1+ (point)) (point-max))))
-- 
2.51.0


--=-=-=
Content-Type: text/plain



-- 
- E.G via Gnus and Org.

--=-=-=--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 27 Oct 2025 17:43:34 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Oct 27 13:43:34 2025
Received: from localhost ([127.0.0.1]:49843 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vDRFl-0006i5-Ep
	for submit <at> debbugs.gnu.org; Mon, 27 Oct 2025 13:43:33 -0400
Received: from mout-p-201.mailbox.org ([2001:67c:2050:0:465::201]:44688)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vDRFe-0006h2-Fp
 for 79671 <at> debbugs.gnu.org; Mon, 27 Oct 2025 13:43:28 -0400
Received: from smtp2.mailbox.org (smtp2.mailbox.org [10.196.197.2])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4cwLSy0w6Pz9tLj;
 Mon, 27 Oct 2025 18:43:14 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1761586994;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
 in-reply-to:in-reply-to:references:references;
 bh=ijKayudZqv+ruBoLUCwXo3Xa081z9+vTNFy20rI3HOE=;
 b=LaR2ulh4BKN3tGWXAdWTDynVJdqsGoNCtu6/7bxHkYW4Xs2T2xmItHAvHZzjL9Ks+Jw1+R
 gSFgAtpbV69UoxKPlEjptL7W1qjBLs109/9WvXgZh9C4cU7r+ZVMU5s/H1zMIa+meWLrYu
 fbUteyAg6sBAoV3IZLVuSY+oCZaV0zYEiVSwF2ropnH0Skwb0E0qQVfn7qDkkHkWvpyC+4
 vEMU1K9aK0io9E/gjSUCc0tL2uk6UdQDpCyJUDQFeJXWzYwE9pk9WrzGR5jzlh/ozbZpnb
 2efmogA5WX+hyhKwnDSO1ieOQPTyJ+9k7BPVtf/yrnYzinINWq/qLThsIZitng==
From: Juri Linkov <juri@HIDDEN>
To: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79671: (WIP) [PATCH] hideshow: Rewrite
 'hs-special-modes-alist'
In-Reply-To: <87plaakege.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
 <87plaakege.fsf@HIDDEN>
Date: Mon, 27 Oct 2025 19:33:54 +0200
Message-ID: <87zf9cs0zh.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

>>>> The 'list' thing was designed to be used for list-related commands
>>>> like 'forward-list', 'backward-list', 'backward-up-list'.
>>>> It is a good approximation for blocks in hs-minor-mode, and it
>>>> still should fall back to 'list' when no other settings are defined
>>>> either by the 'hideshow' thing or in 'hs-special-modes-alist'.
>>>
>>> It will always use `list` if `treesit-things` in
>>> `hs-special-modes-alist` is not defined.
>>
>> Then please use something like this:
>>
>>   (let* ((pred (or (bound-and-true-p hs-treesit-things) 'list))
>
> I meant hideshow will set `hs-treesit-things` to 'list as fallback:
>
> #+begin_src elisp
>               hs-treesit-things (or hs-treesit-things
>                                     (hs--get-mode-value 'treesit-things)
>                                     'list)))
> #+end_src

This is just a stylistic question, what I proposed to do
is to avoid such guards:

  (when (bound-and-true-p hs-treesit-things)

> Here is the updated patch, I'm not sure if this change in
> `hs-special-modes-alist` should be announced in NEWS, since this is a
> drastic change:

Indeed, the most important changes should be announced in NEWS,
and maybe also briefly mentioned in (info "(emacs) Hideshow")
where currently 'hs-special-modes-alist' is only indexed
without any occurrences in the text.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 25 Oct 2025 18:45:54 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Oct 25 14:45:54 2025
Received: from localhost ([127.0.0.1]:42415 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vCjGy-00023c-5y
	for submit <at> debbugs.gnu.org; Sat, 25 Oct 2025 14:45:53 -0400
Received: from mail-ot1-x344.google.com ([2607:f8b0:4864:20::344]:50674)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vCjGu-00023C-DO
 for 79671 <at> debbugs.gnu.org; Sat, 25 Oct 2025 14:45:50 -0400
Received: by mail-ot1-x344.google.com with SMTP id
 46e09a7af769-7c28378681cso1239232a34.1
 for <79671 <at> debbugs.gnu.org>; Sat, 25 Oct 2025 11:45:48 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761417941; x=1762022741; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=70lzpUQC2g3H2zWXmIlqP/C/8GcdueZEN/K5XKihocY=;
 b=QWDx2b5kY9Vn46ZL6K48t6Z30+gBPcezm9Bs1lnMMGYcbSB+ME+xYLxScqv7XsZTIJ
 KBgg0V6TSkCrq+EJBR2SpDTyCHYI8stp//6dkUM59qLEtt7diZpyuqk4Ix9dh238oTSc
 8jtMDWbQa655LxYCDtxHwalWvvjGsUfz+fKRAnuXElSKwhMm3PGRAXswMmmXS5QvoGjc
 1ei+dzQp9iIdC+nj/KOsclY4Ot7VONL8j+RKNJ7M16K7wI/BnQMRwX5jR6V6+cZ1y9Y4
 oUCsDUOF/01OPX1JBNm1hs6wUEY9LoHoqXWBk6YJ8Div24VNqmaChFlH2tec5fFIxoDG
 0iTQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761417941; x=1762022741;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=70lzpUQC2g3H2zWXmIlqP/C/8GcdueZEN/K5XKihocY=;
 b=fPBjUfY7drrPTxd5s0RarRTEv4GzjmbvUWwz6N1jq6tK7NvTr1X2HcdaHATjyitNR/
 A69i1uFWK6H6DfSDMLhbjg90FtdrbTdmsGYLpU37VzsYeHWIUXfWNZC4gEJ7wrh9UreF
 LcZTr4l3FeCyzmg/K+e9TXsWu34oU1snEw/tB/fg2RhMDRPiT+p/bRedbhyCzPW2rHPQ
 ycOUREIEOSwh9yPjnc09bvn9MMfwreF0RBeaDotBQElVefHauRCKDCZb4yjH/djiai3u
 I7g15r4JWsMynRLGVmf45VQ4SwxCHX/JyiW1KNaYywLtigItYcSjqgGhF6noyTmkqcJn
 ECRg==
X-Gm-Message-State: AOJu0YxKXQyE/Qk6eo/fPoUwLOuvsjYpnHz7UPq6v47J6nbFf/XrYtFI
 tasoSLxvFpfaA9viZCSbmDjNwL2NnJMB9xjKXjA1Sk7NfEdEflntLqNoGhHqwpOK
X-Gm-Gg: ASbGncvXBtrnfFQx01SCdmniqwwqbNzMkq9t9prKfaR1PUe9msJS1hUtUjBHshuY5L9
 VcWKAsZAkuUEQD6bWVFdPj0trfBCZtVOdwJWzq3UNvR+y1nsU12/kFc65t7qO3r7Ho4jZG8cN18
 STlz2liFNoLvt4FibxQJIZMR4t19gJ+Hzgg1UlYtwrx1MKDh9MzgGmY6cLeKyzJQ4Lub8rii6KA
 GYYibRwdd55Y3tiKZ/ZCxaaWh4AFoJNYykuq9PgdMTWDsmSwHMUpEgIf45btHuNk57/0CSntlT4
 vkcj3QjmlDicFB1Uzf3kfyune+oJXIPOqtwXwfjcan+SthgN0+g9aM7cE0/PQ7iR/QrDEHwrcHe
 Sy3POLqOIjfO7wWCLZ5TsbifNFB/hSItOKiAuhrcy678fAwpRG7Wq+BzuSJKEozKEFIWABw==
X-Google-Smtp-Source: AGHT+IG/vCooRLZnoieRf2hZQgvdawbhhMBHrkxyPwuln3oRV1IK4m9zw9ZZC2eYh54XqYir//Xclw==
X-Received: by 2002:a05:6808:4f10:b0:44d:a972:f48d with SMTP id
 5614622812f47-44da972f7d5mr720418b6e.51.1761417940863; 
 Sat, 25 Oct 2025 11:45:40 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 5614622812f47-44da3e64f56sm630970b6e.10.2025.10.25.11.45.38
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Sat, 25 Oct 2025 11:45:39 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Juri Linkov <juri@HIDDEN>
Subject: Re: bug#79671: (WIP) [PATCH] hideshow: Rewrite
 'hs-special-modes-alist'
In-Reply-To: <87o6puzyyl.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN> <87o6puzyyl.fsf@HIDDEN>
Date: Sat, 25 Oct 2025 12:45:37 -0600
Message-ID: <87plaakege.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

--=-=-=
Content-Type: text/plain

Juri Linkov <juri@HIDDEN> writes:

>>> The 'list' thing was designed to be used for list-related commands
>>> like 'forward-list', 'backward-list', 'backward-up-list'.
>>> It is a good approximation for blocks in hs-minor-mode, and it
>>> still should fall back to 'list' when no other settings are defined
>>> either by the 'hideshow' thing or in 'hs-special-modes-alist'.
>>
>> It will always use `list` if `treesit-things` in
>> `hs-special-modes-alist` is not defined.
>
> Then please use something like this:
>
>   (let* ((pred (or (bound-and-true-p hs-treesit-things) 'list))

I meant hideshow will set `hs-treesit-things` to 'list as fallback:

#+begin_src elisp
              hs-treesit-things (or hs-treesit-things
                                    (hs--get-mode-value 'treesit-things)
                                    'list)))
#+end_src

Here is the updated patch, I'm not sure if this change in
`hs-special-modes-alist` should be announced in NEWS, since this is a
drastic change:


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow-Rewrite-hs-special-modes-alist.patch

From 3fbb9b700f95871e9b26d49469739bd6e7ccdd2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Mon, 13 Oct 2025 18:45:21 -0600
Subject: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'

Rewrite the format in 'hs-special-modes-alist' to make easier to
exclude some values, add support for settings hierarchy
according to current major mode and parents, add better treesit
things support, define a new setting: 'hs-adjust-block-end', and
support string hiding for lisp modes.

Bug#79671

* lisp/progmodes/hideshow.el (hs-modes-alist): New variable.
(hs-special-modes-alist): Mark as obsolete.
(hs-forward-sexp-func, hs-adjust-block-beginning)
(hs-find-block-beginning-func, hs-find-next-block-func)
(hs-looking-at-block-start-p-func): Set default values to nil.
(hs-adjust-block-end, hs-treesit-things): New buffer-local
variables.
(hs-block-positions): Minor updates.
(hs--get-mode-value): New function.
(hs-grok-mode-type): Rewrite.
* lisp/progmodes/f90.el (hs-special-modes-alist):
* lisp/progmodes/fortran.el (hs-special-modes-alist):
* lisp/progmodes/icon.el (icon-mode):
* lisp/progmodes/lua-mode.el (lua-mode):
* lisp/progmodes/python.el (python-base-mode):
* lisp/progmodes/verilog-mode.el (verilog-mode):
* lisp/progmodes/vhdl-mode.el (vhdl-hs-minor-mode): Rewrite
settings.
* lisp/progmodes/python.el (python-ts-adjust-block-end-fn):
New function.
* lisp/treesit.el (treesit-hs-block-end)
(treesit-hs-find-block-beginning, treesit-hs-find-next-block)
(treesit-hs-looking-at-block-start-p): Minor updates.
---
 lisp/progmodes/f90.el          |  12 +--
 lisp/progmodes/fortran.el      |  12 +--
 lisp/progmodes/hideshow.el     | 153 +++++++++++++++++++++++----------
 lisp/progmodes/icon.el         |  12 +--
 lisp/progmodes/lua-mode.el     |  10 +--
 lisp/progmodes/python.el       |  37 ++++++--
 lisp/progmodes/verilog-mode.el |  12 +--
 lisp/progmodes/vhdl-mode.el    |  10 +--
 lisp/textmodes/mhtml-mode.el   |   2 +-
 lisp/treesit.el                |  99 ++++++++++-----------
 10 files changed, 222 insertions(+), 137 deletions(-)

diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index 96626600d55..c3158069dcd 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -930,7 +930,7 @@ f90-end-block-re
                         "block" "critical") t)
           "\\_>")
   "Regexp matching the end of an F90 \"block\", from the line start.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
 ;; Ignore the fact that FUNCTION, SUBROUTINE, WHERE, FORALL have a
 ;; following "(".  DO, CASE, IF can have labels.
@@ -966,12 +966,12 @@ f90-start-block-re
   "Regexp matching the start of an F90 \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
-;; hs-special-modes-alist is autoloaded.
-(add-to-list 'hs-special-modes-alist
-             `(f90-mode ,f90-start-block-re ,f90-end-block-re
-                        "!" f90-end-of-block nil))
+;; hs-modes-alist is autoloaded.
+(add-to-list 'hs-modes-alist
+             `(f90-mode (start . ,f90-start-block-re) (end . ,f90-end-block-re)
+                        (c-start . "!") (forward-fn . f90-end-of-block)))
 
 
 ;; Imenu support.
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index d1f14fdf8fe..6eb75af01a3 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -549,7 +549,7 @@ fortran-end-block-re
           "\\|!\\|$\\)")
   "Regexp matching the end of a Fortran \"block\", from the line start.
 Note that only ENDDO is handled for the end of a DO-loop.  Used
-in the Fortran entry in `hs-special-modes-alist'.")
+in the Fortran entry in `hs-modes-alist'.")
 
 (defconst fortran-start-block-re
   (concat
@@ -582,11 +582,11 @@ fortran-start-block-re
   "Regexp matching the start of a Fortran \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the Fortran entry in `hs-special-modes-alist'.")
+Used in the Fortran entry in `hs-modes-alist'.")
 
-(add-to-list 'hs-special-modes-alist
-             `(fortran-mode ,fortran-start-block-re ,fortran-end-block-re
-                            "^[cC*!]" fortran-end-of-block nil))
+(add-to-list 'hs-modes-alist
+             `(fortran-mode (start . ,fortran-start-block-re) (end . ,fortran-end-block-re)
+                            (c-start . "^[cC*!]") (forward-fn . fortran-end-of-block)))
 
 
 (defvar fortran-mode-syntax-table
@@ -1247,7 +1247,7 @@ fortran-looking-at-if-then
           (goto-char i)
           (= (line-beginning-position) p)))))
 
-;; Used in hs-special-modes-alist.
+;; Used in hs-modes-alist.
 (defun fortran-end-of-block (&optional num)
   "Move point forward to the end of the current code block.
 With optional argument NUM, go forward that many balanced blocks.
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index 6158253ee53..88a349afe94 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -370,30 +370,41 @@ hs-indicator-show
   :version "31.1")
 
 ;;;###autoload
-(defvar hs-special-modes-alist
-  ;; FIXME: Currently the check is made via
-  ;; (assoc major-mode hs-special-modes-alist) so it doesn't pay attention
-  ;; to the mode hierarchy.
-  '((c-mode "{" "}" "/[*/]" nil nil)
-    (c-ts-mode "{" "}" "/[*/]" nil nil)
-    (c++-mode "{" "}" "/[*/]" nil nil)
-    (c++-ts-mode "{" "}" "/[*/]" nil nil)
-    (bibtex-mode ("@\\S(*\\(\\s(\\)" 1))
-    (java-mode "{" "}" "/[*/]" nil nil)
-    (java-ts-mode "{" "}" "/[*/]" nil nil)
-    (js-mode "{" "}" "/[*/]" nil)
-    (js-ts-mode "{" "}" "/[*/]" nil)
-    (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil)
+(defvar hs-special-modes-alist nil)
+(make-obsolete-variable 'hs-special-modes-alist 'hs-modes-alist "31.1")
+
+;;;###autoload
+(defvar hs-modes-alist
+  '((c-mode    (start . "{") (end . "}") (c-start . "/[*/]"))
+    (c++-mode  (start . "{") (end . "}") (c-start . "/[*/]"))
+    (java-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (bibtex-mode  (start . ("@\\S(*\\(\\s(\\)" 1)))
+    (js-base-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (sgml-mode (start . "<[^/>]*?") (end . "</[^/>]*[^/]>")
+               (c-start . "<!--") (forward-fn . sgml-skip-tag-forward))
+    (html-mode (start . "{\\|<[^/>]*?") (end . "}\\|</[^/>]*[^/]>")
+               (forward-fn . forward-sexp))
+    (mhtml-mode (forward-fn . mhtml-forward))
+    (lisp-data-mode (start . "\\s(\\|\"") (end . "\\s)\\|\""))
     ;; Add more support here.
     )
   "Alist for initializing the hideshow variables for different modes.
-Each element has the form
-  (MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC
-   FIND-BLOCK-BEGINNING-FUNC FIND-NEXT-BLOCK-FUNC
-   LOOKING-AT-BLOCK-START-P-FUNC).
+Each element is an alist with any of the cons-cells forms:
+ (MODE &optional
+       (start . START)
+       (end . END)
+       (c-start . COMMENT-START)
+       (forward-fn . FORWARD-SEXP-FUNC)
+       (adjust-beg-fn . ADJUST-BEG-FUNC)
+       (adjust-end-fn . ADJUST-END-FUNC)
+       (find-beg-fn . FIND-BLOCK-BEGINNING-FUNC)
+       (find-next-fn . FIND-NEXT-BLOCK-FUNC)
+       (look-start-fn . LOOKING-AT-BLOCK-START-P-FUNC)
+       (treesit-things . TREESIT-THINGS))
 
 If non-nil, hideshow will use these values as regexps to define blocks
-and comments, respectively for major mode MODE.
+and comments, respectively for major mode MODE or current major mode
+parents.
 
 START, END and COMMENT-START are regular expressions.  A block is
 defined as text surrounded by START and END.
@@ -403,7 +414,7 @@ hs-special-modes-alist
 MDATA-SELECTOR an integer that specifies which sub-match is the proper
 place to adjust point, before calling `hs-forward-sexp-func'.  Point
 is adjusted to the beginning of the specified match.  For example,
-see the `hs-special-modes-alist' entry for `bibtex-mode'.
+see the `hs-modes-alist' entry for `bibtex-mode'.
 
 For some major modes, `forward-sexp' does not work properly.  In those
 cases, FORWARD-SEXP-FUNC specifies another function to use instead.
@@ -411,6 +422,9 @@ hs-special-modes-alist
 See the documentation for `hs-adjust-block-beginning' to see what is the
 use of ADJUST-BEG-FUNC.
 
+See the documentation for `hs-adjust-block-end' to see what is the
+use of ADJUST-END-FUNC.
+
 See the documentation for `hs-find-block-beginning-func' to see
 what is the use of FIND-BLOCK-BEGINNING-FUNC.
 
@@ -420,7 +434,13 @@ hs-special-modes-alist
 See the documentation for `hs-looking-at-block-start-p-func' to
 see what is the use of LOOKING-AT-BLOCK-START-P-FUNC.
 
-If any of the elements is left nil or omitted, hideshow tries to guess
+TREESIT-THINGS is a thing defined in `treesit-thing-settings' to
+determine if current block at point is valid, see
+`treesit-thing-settings' to get more information about.
+
+All the elements supports mode hierarchy.  If any of the elements is
+left nil or omitted, hideshow searches for a value defined in some
+parent mode in this alist, if no value is found, it tries to guess the
 appropriate values.  The regexps should not contain leading or trailing
 whitespace.  Case does not matter.")
 
@@ -548,7 +568,7 @@ hs-block-start-mdata-select
 (defvar-local hs-block-end-regexp nil
   "Regexp for end of block.")
 
-(defvar-local hs-forward-sexp-func #'forward-sexp
+(defvar-local hs-forward-sexp-func nil
   "Function used to do a `forward-sexp'.
 Should change for Algol-ish modes.  For single-character block
 delimiters -- ie, the syntax table regexp for the character is
@@ -556,7 +576,7 @@ hs-forward-sexp-func
 `forward-sexp'.  For other modes such as simula, a more specialized
 function is necessary.")
 
-(defvar-local hs-adjust-block-beginning #'identity
+(defvar-local hs-adjust-block-beginning nil
   "Function used to tweak the block beginning.
 The block is hidden from the position returned by this function,
 as opposed to hiding it from the position returned when searching
@@ -576,7 +596,16 @@ hs-adjust-block-beginning
 
 See `hs-c-like-adjust-block-beginning' for an example of using this.")
 
-(defvar-local hs-find-block-beginning-func #'hs-find-block-beginning
+(defvar-local hs-adjust-block-end nil
+  "Function used to tweak the block end.
+This is useful to ensure some characters such as parenthesis or curly
+braces get properly hidden in python-like modes.
+
+It is called with 1 argument which is the hiding beginning position.
+
+It should return the position from where the hiding ends.")
+
+(defvar-local hs-find-block-beginning-func nil
   "Function used to do `hs-find-block-beginning'.
 It should reposition point at the beginning of the current block
 and return point, or nil if original point was not in a block.
@@ -585,7 +614,7 @@ hs-find-block-beginning-func
 Python, where regexp search and `syntax-ppss' check is not enough
 to find the beginning of the current block.")
 
-(defvar-local hs-find-next-block-func #'hs-find-next-block
+(defvar-local hs-find-next-block-func nil
   "Function used to do `hs-find-next-block'.
 It should reposition point at next block start.
 
@@ -601,7 +630,7 @@ hs-find-next-block-func
 Python, where regexp search is not enough to find the beginning
 of the next block.")
 
-(defvar-local hs-looking-at-block-start-p-func #'hs-looking-at-block-start-p
+(defvar-local hs-looking-at-block-start-p-func nil
   "Function used to do `hs-looking-at-block-start-p'.
 It should return non-nil if the point is at the block start.
 
@@ -612,6 +641,11 @@ hs-looking-at-block-start-p-func
 (defvar-local hs-inside-comment-p-func nil
   "Function used to check if point is inside a comment.")
 
+(defvar-local hs-treesit-things nil
+  "Treesit things to check if point is at a valid block.
+The value should be a thing defined in `treesit-thing-settings' for the
+current buffer's major mode.")
+
 (defvar hs-headline nil
   "Text of the line where a hidden block begins, set during isearch.
 You can display this in the mode line by adding the symbol `hs-headline'
@@ -703,8 +737,7 @@ hs-block-positions
           ;; `block-start' is the point at the end of the block
           ;; beginning, which may need to be adjusted
           (save-excursion
-            (goto-char (funcall (or hs-adjust-block-beginning #'identity)
-                                header-end))
+            (goto-char (funcall hs-adjust-block-beginning header-end))
             (setq block-beg (line-end-position)))
           ;; `block-end' is the point at the end of the block
           (hs-forward-sexp mdata 1)
@@ -716,7 +749,8 @@ hs-block-positions
                        (funcall hs-block-end-regexp)
                        (match-beginning 0))
                       (t (point))))
-          (cons block-beg block-end))))))
+          (cons block-beg
+                (or (funcall hs-adjust-block-end block-beg) block-end)))))))
 
 (defun hs--make-indicators-overlays (beg)
   "Helper function to make the indicators overlays."
@@ -987,16 +1021,31 @@ hs-inside-comment-p--default
           (when (>= (point) q)
             (list (and hideable p) (point))))))))
 
+(defun hs--get-mode-value (value &optional old-nth)
+  "Get VALUE for current major mode in `hs-modes-alist'.
+OLD-NTH is only used for backward compatibility with
+`hs-special-modes-alist'."
+  (if-let* (old-nth
+            (old-lookup (assoc major-mode hs-special-modes-alist)))
+      (nth old-nth old-lookup)
+    (catch 'hs-grok-exit
+      (dolist (modes (get major-mode 'derived-mode--all-parents))
+        ;; If we cannot find VALUE in current MODES, try to find it in
+        ;; the next mode in MODES
+        (if-let* ((list (assoc modes hs-modes-alist))
+                  (elm (alist-get value list)))
+            (throw 'hs-grok-exit elm))))))
+
 (defun hs-grok-mode-type ()
   "Set up hideshow variables for new buffers.
-If `hs-special-modes-alist' has information associated with the
+If `hs-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 (bound-and-true-p comment-start)
            (bound-and-true-p comment-end))
-      (let* ((lookup (assoc major-mode hs-special-modes-alist))
-             (start-elem (or (nth 1 lookup) "\\s(")))
+      (let ((start-elem (or (hs--get-mode-value 'start 1) "\\s(")))
+
         (if (listp start-elem)
             ;; handle (START-REGEXP MDATA-SELECT)
             (setq hs-block-start-regexp (car start-elem)
@@ -1004,23 +1053,39 @@ hs-grok-mode-type
           ;; 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)
+
+        (setq hs-block-end-regexp (or hs-block-end-regexp
+                                      (hs--get-mode-value 'end 2)
+                                      "\\s)")
+              hs-c-start-regexp (or hs-c-start-regexp
+                                    (hs--get-mode-value 'c-start 3)
                                     (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 (or (nth 5 lookup) #'identity)
-              hs-find-block-beginning-func (or (nth 6 lookup)
+              hs-forward-sexp-func (or hs-forward-sexp-func
+                                       (hs--get-mode-value 'forward-fn 4)
+                                       #'forward-sexp)
+              hs-adjust-block-beginning (or hs-adjust-block-beginning
+                                            (hs--get-mode-value 'adjust-fn 5)
+                                            #'identity)
+              hs-adjust-block-end (or hs-adjust-block-end
+                                      (hs--get-mode-value 'adjust-end-fn 5)
+                                      #'ignore)
+              hs-find-block-beginning-func (or hs-find-block-beginning-func
+                                               (hs--get-mode-value 'find-beg-fn 6)
                                                #'hs-find-block-beginning)
-              hs-find-next-block-func (or (nth 7 lookup)
+              hs-find-next-block-func (or hs-find-next-block-func
+                                          (hs--get-mode-value 'find-next-fn 7)
                                           #'hs-find-next-block)
-              hs-looking-at-block-start-p-func
-              (or (nth 8 lookup)
-                  #'hs-looking-at-block-start-p)))
+              hs-looking-at-block-start-p-func (or hs-looking-at-block-start-p-func
+                                                   (hs--get-mode-value 'look-start-fn 8)
+                                                   #'hs-looking-at-block-start-p)
+              hs-treesit-things (or hs-treesit-things
+                                    (hs--get-mode-value 'treesit-things)
+                                    'list)))
     (setq hs-minor-mode nil)
     (error "%s Mode doesn't support Hideshow Minor Mode"
            (format-mode-line mode-name))))
@@ -1341,10 +1406,8 @@ hs-minor-mode
   (setq hs-headline nil)
   (if hs-minor-mode
       (progn
-        ;; Use such heuristics that if one buffer-local variable
-        ;; is already defined, don't overwrite other variables too.
-        (unless (buffer-local-value 'hs-inside-comment-p-func (current-buffer))
-          (hs-grok-mode-type))
+        ;; Set the variables according to `hs-modes-alist'.
+        (hs-grok-mode-type)
         ;; Turn off this mode if we change major modes.
         (add-hook 'change-major-mode-hook
                   #'turn-off-hideshow
diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el
index dee57956ce7..2a5172609d9 100644
--- a/lisp/progmodes/icon.el
+++ b/lisp/progmodes/icon.el
@@ -167,12 +167,12 @@ icon-mode
   ;; imenu support
   (setq-local imenu-generic-expression icon-imenu-generic-expression)
   ;; hideshow support
-  ;; we start from the assertion that `hs-special-modes-alist' is autoloaded.
-  (unless (assq 'icon-mode hs-special-modes-alist)
-    (setq hs-special-modes-alist
-	  (cons '(icon-mode  "\\<procedure\\>" "\\<end\\>" nil
-			     icon-forward-sexp-function)
-		hs-special-modes-alist))))
+  ;; we start from the assertion that `hs-modes-alist' is autoloaded.
+  (unless (assq 'icon-mode hs-modes-alist)
+    (setq hs-modes-alist
+	  (cons '(icon-mode  (start . "\\<procedure\\>") (end . "\\<end\\>")
+                             (forward-fn . icon-forward-sexp-function))
+		hs-modes-alist))))
 
 ;; This is used by indent-for-comment to decide how much to
 ;; indent a comment in Icon code based on its context.
diff --git a/lisp/progmodes/lua-mode.el b/lisp/progmodes/lua-mode.el
index 01d91637cf0..07b3777c988 100644
--- a/lisp/progmodes/lua-mode.el
+++ b/lisp/progmodes/lua-mode.el
@@ -553,12 +553,12 @@ lua-mode
   (add-hook 'flymake-diagnostic-functions #'lua-flymake nil t)
 
   ;; Hide-show setup
-  (unless (assq 'lua-mode hs-special-modes-alist)
-    (add-to-list 'hs-special-modes-alist
+  (unless (assq 'lua-mode hs-modes-alist)
+    (add-to-list 'hs-modes-alist
                  `(lua-mode
-                   ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words) ; Start
-                   ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words) ; End
-                   nil lua-forward-sexp))))
+                   (start . ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words)) ; Start
+                   (end . ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words)) ; End
+                   (forward-fn . lua-forward-sexp)))))
 
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 5a96972caa7..e1df123d172 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -5912,6 +5912,20 @@ python-hideshow-find-next-block
         (beginning-of-line)
         (looking-at regexp)))))
 
+(defun python-ts-adjust-block-end-fn (block-beg)
+  "Python-ts-mode specific `hs-adjust-block-end' function for `hs-minor-mode'.
+
+BLOCK-BEG is the beginning position where the hiding will be performed.
+
+This is only used to ensure the block end position in function
+definitions and parens."
+  (unless (save-excursion
+            (goto-char block-beg)
+            (treesit-thing-at
+             (if (bobp) (point) (1- (point)))
+             '(or "argument_list" (and anonymous "\\`[](),[{}]\\'"))))
+    (line-end-position)))
+
 
 ;;; Imenu
 
@@ -7342,18 +7356,23 @@ python-base-mode
   ;; TODO: Use tree-sitter to figure out the block in `python-ts-mode'.
   (dolist (mode '(python-mode python-ts-mode))
     (add-to-list
-     'hs-special-modes-alist
+     'hs-modes-alist
      `(,mode
-       ,python-nav-beginning-of-block-regexp
+       (start . ,python-nav-beginning-of-block-regexp)
        ;; Use the empty string as end regexp so it doesn't default to
        ;; "\\s)".  This way parens at end of defun are properly hidden.
-       ""
-       "#"
-       python-hideshow-forward-sexp-function
-       nil
-       python-nav-beginning-of-block
-       python-hideshow-find-next-block
-       python-info-looking-at-beginning-of-block)))
+       (end . "")
+       (c-start . "#")
+       (forward-fn . python-hideshow-forward-sexp-function)
+       (find-beg-fn . python-nav-beginning-of-block)
+       (find-next-fn . python-hideshow-find-next-block)
+       (look-start-fn . python-info-looking-at-beginning-of-block)
+       (treesit-things . (or defun sexp)))))
+
+  (add-to-list
+   'hs-modes-alist
+   '(python-ts-mode
+     (adjust-end-fn . python-ts-adjust-block-end-fn)))
 
   (setq-local outline-regexp (python-rx (* space) block-start))
   (setq-local outline-level
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 2f5525786e1..81fecec806f 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -4363,12 +4363,12 @@ verilog-mode
   (when (and (boundp 'which-func-modes) (listp which-func-modes))
     (add-to-list 'which-func-modes 'verilog-mode))
   ;; hideshow support
-  (when (boundp 'hs-special-modes-alist)
-    (unless (assq 'verilog-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-            (cons '(verilog-mode "\\<begin\\>" "\\<end\\>" nil
-                                 verilog-forward-sexp-function)
-                  hs-special-modes-alist))))
+  (when (boundp 'hs-modes-alist)
+    (unless (assq 'verilog-mode hs-modes-alist)
+      (setq hs-modes-alist
+            (cons '(verilog-mode (beg . "\\<begin\\>") (end . "\\<end\\>")
+                                 (forward-fn . verilog-forward-sexp-function))
+                  hs-modes-alist))))
 
   (add-hook 'completion-at-point-functions
             #'verilog-completion-at-point nil 'local)
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 593a83ceffa..82e6f41e07e 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -13282,11 +13282,11 @@ vhdl-hs-minor-mode
   (if (not (boundp 'hs-block-start-mdata-select))
       (vhdl-warning-when-idle "Install included `hideshow.el' patch first (see INSTALL file)")
     ;; initialize hideshow
-    (unless (assoc 'vhdl-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-	    (cons (list 'vhdl-mode vhdl-hs-start-regexp nil "--\\( \\|$\\)"
-			'vhdl-hs-forward-sexp-func nil)
-		  hs-special-modes-alist)))
+    (unless (assoc 'vhdl-mode hs-modes-alist)
+      (setq hs-modes-alist
+	    (cons `(vhdl-mode (start . ,vhdl-hs-start-regexp) (c-start . "--\\( \\|$\\)")
+			      (forward-fn . vhdl-hs-forward-sexp-func))
+		  hs-modes-alist)))
     (if (featurep 'xemacs) (make-local-hook 'hs-minor-mode-hook))
     (if vhdl-hide-all-init
 	(add-hook 'hs-minor-mode-hook #'hs-hide-all nil t)
diff --git a/lisp/textmodes/mhtml-mode.el b/lisp/textmodes/mhtml-mode.el
index e1ea73dc9ac..4ab560df6a8 100644
--- a/lisp/textmodes/mhtml-mode.el
+++ b/lisp/textmodes/mhtml-mode.el
@@ -306,7 +306,7 @@ mhtml--flyspell-check-word
         (flyspell-generic-progmode-verify)
       t)))
 
-;; Support for hideshow.el (see `hs-special-modes-alist').
+;; Support for hideshow.el (see `hs-modes-alist').
 (defun mhtml-forward (arg)
   "Move point forward past a structured expression.
 If point is on a tag, move to the end of the tag.
diff --git a/lisp/treesit.el b/lisp/treesit.el
index a8a515c434d..717472b58fd 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -4230,65 +4230,68 @@ treesit-outline-level
 
 (defun treesit-hs-block-end ()
   "Tree-sitter implementation of `hs-block-end-regexp'."
-  (let* ((pred 'list)
-         (thing (treesit-thing-at
-                 (if (bobp) (point) (1- (point))) pred))
-         (end (when thing (treesit-node-end thing)))
-         (last (when thing (treesit-node-child thing -1)))
-         (beg (if last (treesit-node-start last)
-                (if (bobp) (point) (1- (point))))))
-    (when (and thing (eq (point) end))
-      (set-match-data (list beg end))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((thing (treesit-thing-at
+                   (if (bobp) (point) (1- (point))) hs-treesit-things))
+           (end (when thing (treesit-node-end thing)))
+           (last (when thing (treesit-node-child thing -1)))
+           (beg (if last (treesit-node-start last)
+                  (if (bobp) (point) (1- (point))))))
+      (when (and thing (eq (point) end))
+        (set-match-data (list beg end))
+        t))))
 
 (defun treesit-hs-find-block-beginning ()
   "Tree-sitter implementation of `hs-find-block-beginning-func'."
-  (let* ((pred 'list)
-         (thing (treesit-thing-at (point) pred))
-         (beg (when thing (treesit-node-start thing)))
-         (end (when beg (min (1+ beg) (point-max)))))
-    (when thing
-      (goto-char beg)
-      (set-match-data (list beg end))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((thing (treesit-thing-at (point) hs-treesit-things))
+           (beg (when thing (treesit-node-start thing)))
+           (end (when beg (min (1+ beg) (point-max)))))
+      (when thing
+        (goto-char beg)
+        (set-match-data (list beg end))
+        t))))
 
 (defun treesit-hs-find-next-block (_regexp maxp comments)
   "Tree-sitter implementation of `hs-find-next-block-func'."
   (when (not comments)
     (forward-comment (point-max)))
-  (let* ((comment-pred
-          (when comments
-            (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
-                'comment "\\`comment\\'")))
-         (pred (if comment-pred (append '(or list) (list comment-pred)) 'list))
-         ;; `treesit-navigate-thing' can't find a thing at bobp,
-         ;; so use `treesit-thing-at' to match at bobp.
-         (current (treesit-thing-at (point) pred))
-         (beg (or (and current (eq (point) (treesit-node-start current)) (point))
-                  (treesit-navigate-thing (point) 1 'beg pred)))
-         ;; Check if we found a list or a comment
-         (list-thing (when beg (treesit-thing-at beg 'list)))
-         (comment-thing (when beg (treesit-thing-at beg comment-pred)))
-         (comment-p (and comment-thing (eq beg (treesit-node-start comment-thing))))
-         (thing (if comment-p comment-thing list-thing))
-         (end (if thing (min (1+ (treesit-node-start thing)) (point-max)))))
-    (when (and end (<= end maxp))
-      (goto-char end)
-      (set-match-data
-       (if (and comments comment-p)
-           (list beg end nil nil beg end)
-         (list beg end beg end)))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((comment-pred
+            (when comments
+              (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
+                  'comment "\\`comment\\'")))
+           (pred (if comment-pred
+                     (append `(or ,hs-treesit-things) (list comment-pred))
+                   hs-treesit-things))
+           ;; `treesit-navigate-thing' can't find a thing at bobp,
+           ;; so use `treesit-thing-at' to match at bobp.
+           (current (treesit-thing-at (point) pred))
+           (beg (or (and current (eq (point) (treesit-node-start current)) (point))
+                    (treesit-navigate-thing (point) 1 'beg pred)))
+           ;; Check if we found a block or a comment
+           (block-thing (when beg (treesit-thing-at beg hs-treesit-things)))
+           (comment-thing (when beg (treesit-thing-at beg comment-pred)))
+           (comment-p (and comment-thing (eq beg (treesit-node-start comment-thing))))
+           (thing (if comment-p comment-thing block-thing))
+           (end (if thing (min (1+ (treesit-node-start thing)) (point-max)))))
+      (when (and end (<= end maxp))
+        (goto-char end)
+        (set-match-data
+         (if (and comments comment-p)
+             (list beg end nil nil beg end)
+           (list beg end beg end)))
+        t))))
 
 (defun treesit-hs-looking-at-block-start-p ()
   "Tree-sitter implementation of `hs-looking-at-block-start-p-func'."
-  (let* ((pred 'list)
-         (thing (treesit-thing-at (point) pred))
-         (beg (when thing (treesit-node-start thing)))
-         (end (min (1+ (point)) (point-max))))
-    (when (and thing (eq (point) beg))
-      (set-match-data (list beg end))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((thing (treesit-thing-at (point) hs-treesit-things))
+           (beg (when thing (treesit-node-start thing)))
+           (end (min (1+ (point)) (point-max))))
+      (when (and thing (eq (point) beg))
+        (set-match-data (list beg end))
+        t))))
 
 (defun treesit-hs-inside-comment-p ()
   "Tree-sitter implementation of `hs-inside-comment-p-func'."
-- 
2.51.0


--=-=-=
Content-Type: text/plain


-- 
- E.G via Gnus and Org.

--=-=-=--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 25 Oct 2025 17:17:25 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Oct 25 13:17:25 2025
Received: from localhost ([127.0.0.1]:42312 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vChtN-0005cs-4Y
	for submit <at> debbugs.gnu.org; Sat, 25 Oct 2025 13:17:25 -0400
Received: from mout-p-201.mailbox.org ([2001:67c:2050:0:465::201]:49412)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vChtK-0005cP-RB
 for 79671 <at> debbugs.gnu.org; Sat, 25 Oct 2025 13:17:24 -0400
Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4cv5zq3fCfz9t8R;
 Sat, 25 Oct 2025 19:17:11 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1761412631;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
 in-reply-to:in-reply-to:references:references;
 bh=s7Lsy/2mzgfxzP/KgzKwo6IOvf3eBaFVjdBDJYFj8Jg=;
 b=vYKnbfEvXH4RcUgVKKYec/NcAlC0IrEJ3eholZopDSWIxnUyXzQkzB56rke7yK488kTxKf
 eLNlAyqDa8s+KnOVnq+YQABsqZfIwxxCJhswGTeAO+V4as88Ovq8MGAtWXnmTyWsVH6pG/
 MHFS6Ez2ay4KXVG1KJ1vkhlI8BAqwSlUYVpJTfOo6HrzkpUaf0t9A/3NlC1JrgIAfEs86i
 I+6xVOdCg4B9GaczNPZe4K+Lz9zYBVYjqKqU2WW7ZcQV/3y7qQ/q6zHdMaXK6sQkjfGTrk
 0eb7st2/eWz9vvmugE4dfbaiGJbb7cpPRippb/QkjtfZlAbuafWrSoGpDo5fGQ==
From: Juri Linkov <juri@HIDDEN>
To: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79671: (WIP) [PATCH] hideshow: Rewrite
 'hs-special-modes-alist'
In-Reply-To: <87qzuscaxg.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
 <87qzuscaxg.fsf@HIDDEN>
Date: Sat, 25 Oct 2025 20:13:39 +0300
Message-ID: <87o6puzyyl.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

> I've updated the patch, so it can also support better settings
> hierarchy.
>
> e.g.
>
> #+begin_src elisp
>   '((html-mode (start . "{\\|<[^/>]*?") (end . "}\\|</[^/>]*[^/]>"))
>     (mhtml-mode (forward-fn . mhtml-forward)))
> #+end_src
>
> here mhtml-mode will inherit the `start` and `end` settings from
> html-mode, but it will use `mhtml-forward` for `forward-fn`.

Thanks, more granular inheritance is much better.

>> The 'list' thing was designed to be used for list-related commands
>> like 'forward-list', 'backward-list', 'backward-up-list'.
>> It is a good approximation for blocks in hs-minor-mode, and it
>> still should fall back to 'list' when no other settings are defined
>> either by the 'hideshow' thing or in 'hs-special-modes-alist'.
>
> It will always use `list` if `treesit-things` in
> `hs-special-modes-alist` is not defined.

Then please use something like this:

  (let* ((pred (or (bound-and-true-p hs-treesit-things) 'list))

> Also, I found that using `defun` in python-ts-mode didn't work at all.
>
> #+begin_src python
> def test_func(arg):
>     return arg
>
> # gets folded to this:
> def test_func(arg):[...]g
> #+end_src
>
> So i had to create a new variable/setting in hideshow to prevent this.
>
> I don't know if there was a better way to prevent this, but possibly
> this addition can make the hiding more versatile.

I noticed this problem too in languages without explicit closing parens,
where last characters were used.  Adding a new settings looks like
the right thing to prevent this.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 24 Oct 2025 20:16:58 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Oct 24 16:16:58 2025
Received: from localhost ([127.0.0.1]:38360 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vCODY-0002ZE-Ao
	for submit <at> debbugs.gnu.org; Fri, 24 Oct 2025 16:16:58 -0400
Received: from mail-oi1-x242.google.com ([2607:f8b0:4864:20::242]:61463)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vCODU-0002Yz-8c
 for 79671 <at> debbugs.gnu.org; Fri, 24 Oct 2025 16:16:54 -0400
Received: by mail-oi1-x242.google.com with SMTP id
 5614622812f47-44d9b956657so281051b6e.2
 for <79671 <at> debbugs.gnu.org>; Fri, 24 Oct 2025 13:16:52 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761337006; x=1761941806; darn=debbugs.gnu.org;
 h=mime-version:message-id:date:references:in-reply-to:subject:cc:to
 :from:from:to:cc:subject:date:message-id:reply-to;
 bh=MgzoAr/wRP2iuhBLWrP10xV3iO7vGVgFag6RzP8yOLE=;
 b=PigdqUYEFUlK+ARt/Tb0TuWJbClk5CHJvbCCbahk7OSPJD23m2UmvqVjYjJEkes6pT
 U0hlpNBmzm1PjtUEzVwOA+8sgU58BdBExmTxs1In1YwwSAnWFzP+CalCP8ewdXNvkdeA
 JaoyLGI64MJzjrwRlgh6fqPmUshOof83DndIX2AxRCAQtP1m/IKit+2tPhF0lT8eXIMD
 WDhOz4z3ngd1Wzcaeg2kXbmdDfr2B5b0sHPRs4Vd5m+6CxuMlVCd5cUkX0Y3S8rT+PUr
 0l1HtOJEMav0eHgw/nAK0gmBrJYFBHvmUZTehmbU31ok+S06miUX2HpqP2CaTlRXr86i
 rCkQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761337006; x=1761941806;
 h=mime-version:message-id:date:references:in-reply-to:subject:cc:to
 :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
 bh=MgzoAr/wRP2iuhBLWrP10xV3iO7vGVgFag6RzP8yOLE=;
 b=iJmDWxCu6bKZjSpRQE6Vg7wmTSklqUTXSsY5cgnKYoMWN26IPX5VYTer73gJG4Faol
 oLqmk8xhQ1XBNk3uy+6wwz472u/NdkivemZXhjgqw6PUSG9u4LobIUbTf7Six1faXId/
 s/vwmB+EdzE/hssQWL6Y06/UnF+ZaPe5VmtgvKXFG3K4oA/vqJRvFORCz1TbrHWxNlFf
 3wy7miv/afEeZjfJUI9uYF7ju2/4++e7sq4m8+HlEz1fTZWte5XsjDtVaOAoo9pNnNpb
 JcIBavXSJVsqEPMLCIO5nZC7CbhjgA+F8sBi1C/vHxGeOAp97eyDdWvUIJAXvknCQJOr
 sRrw==
X-Gm-Message-State: AOJu0YyjlbN88O1LpsP4Z7gux0XMXbdYXKynazxJKcFsH3KeTf5JRDbJ
 Ei9St+91swC+H51YHwr4O4HX3Pl0eWMMym4kSRVVCd5UVOc6xxarrmkJYoipd7p9
X-Gm-Gg: ASbGnctxTVO1TndF7FO+KtIXmRa/mbOwnbYljVOJo9NBrZXqffXRGcz+m4OYkkmKFhD
 +yCILHdxjjgvOqdvWkgsTCn86NrY+wGUjjNg/n3SrrxPSafF1i9pT6PEoCxlEUGqHeALsOVBJSK
 FCtkIcMMiXt1V89rGuj80MhFQh0u7KftjwnRvcC537CaViLx4FU999Fomp8BHPfyy/WcBrLNJqD
 4P48JbO8eyn29Sj2I2DQzEMAf8ebVUhJB9ie5nLRu55FklwtWRa2/0WBq3Zuud2TVrXYuVhRDPL
 I7D4dH/wml9MXi80QUY6p22kwJnamLxUiK5roAEhB+MgXvfc5hsR5Ba5Mv80CMs05QKpa6P/8Sb
 EQse2b7zm8y6Ue6RVnDD+FA5jb+zx8/OFcGahuZ/NFr1fEmmhoaKpdGfuAZdNeTRki8f/dg==
X-Google-Smtp-Source: AGHT+IFAPDaVTF1mMnI5wZtayFEijcUtRT1UWzDEkQQmadlrg6rKDDYx9+9JOtAMDRqf2HN0SNDMCA==
X-Received: by 2002:a05:6808:308b:b0:441:8f74:fc1 with SMTP id
 5614622812f47-443a31bd78fmr12631407b6e.62.1761337005675; 
 Fri, 24 Oct 2025 13:16:45 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 5614622812f47-44da3e93e0esm26680b6e.17.2025.10.24.13.16.44
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Fri, 24 Oct 2025 13:16:45 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Juri Linkov <juri@HIDDEN>
Subject: Re: bug#79671: (WIP) [PATCH] hideshow: Rewrite
 'hs-special-modes-alist'
In-Reply-To: <87347a2kc1.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN> <87347a2kc1.fsf@HIDDEN>
Date: Fri, 24 Oct 2025 14:16:43 -0600
Message-ID: <87qzuscaxg.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

--=-=-=
Content-Type: text/plain

Juri Linkov <juri@HIDDEN> writes:

>> It should also apply to the current derived mode.
>>
>> e.g.  If nxml-mode is not defined in `hs-special-modes-alist`, it will
>> try to find a parent mode in `hs-special-modes-alist`.
>
> Sorry, it seems I was mistaken.  By re-reading your patch I see
> that it already supports overriding parent settings.  For example,
> if the user wants mhtml settings to override html settings,
> this will be possible to customize with:
>
>  (setopt hs-special-modes-alist
>    '((mhtml-mode <some mhtml-specific settings>)
>      (html-mode <some html settings>))

I've updated the patch, so it can also support better settings
hierarchy.

e.g.
#+begin_src elisp
  '((html-mode (start . "{\\|<[^/>]*?") (end . "}\\|</[^/>]*[^/]>"))
    (mhtml-mode (forward-fn . mhtml-forward)))
#+end_src

here mhtml-mode will inherit the `start` and `end` settings from
html-mode, but it will use `mhtml-forward` for `forward-fn`.

>>>> - Change 'hs-special-modes-alist' format.
>>>
>>> I suppose the old format will still be supported for backward-compatibility?
>>
>> Yes, but currently it has no effect.  I'm thinking about define a new
>> variable as a replacement for 'hs-special-modes-alist', and mark
>> 'hs-special-modes-alist' as obsolete but with compatibility.
>
> A new variable with a shorter name like 'hs-modes-alist'
> is also a variant indeed.

Thanks.  I've added it in the patch.

>>>> - Add an easy way to support treesit
>>>>
>>>> The treesit support in hideshow is partial, some modes (such as
>>>> python-ts-mode) do not fully support folding with treesit (e.g. def).
>>>
>>> Currently hs-minor-mode uses the hard-coded 'list' thing, which
>>> e.g. in python-ts-mode doesn't include 'function_definition'
>>> for compatibility with python-mode.
>>>
>>> But to make this configurable, we could add a new thing, e.g. 'hideshow',
>>> to be defined in 'treesit-thing-settings' instead of 'hs-special-modes-alist'.
>>> Or maybe better to support both.
>>
>> Was not the 'list' thing designed to be used in hideshow?
>
> The 'list' thing was designed to be used for list-related commands
> like 'forward-list', 'backward-list', 'backward-up-list'.
> It is a good approximation for blocks in hs-minor-mode, and it
> still should fall back to 'list' when no other settings are defined
> either by the 'hideshow' thing or in 'hs-special-modes-alist'.

It will always use `list` if `treesit-things` in
`hs-special-modes-alist` is not defined.

Also, I found that using `defun` in python-ts-mode didn't work at all.

#+begin_src python
def test_func(arg):
    return arg

# gets folded to this:
def test_func(arg):[...]g
#+end_src

So i had to create a new variable/setting in hideshow to prevent this.

I don't know if there was a better way to prevent this, but possibly
this addition can make the hiding more versatile.


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow-Rewrite-hs-special-modes-alist.patch

From 3b50da01d594121b48bd127592468d988c25634a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Mon, 13 Oct 2025 18:45:21 -0600
Subject: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'

Rewrite the format in 'hs-special-modes-alist' to make easier to
exclude some values, add support for settings hierarchy
according to current major mode and parents, add better treesit
things support, and define a new setting: 'hs-adjust-block-end'.

bug#79671

* lisp/progmodes/hideshow.el (hs-modes-alist): New variable.
(hs-special-modes-alist): Mark as obsolete.
(hs-forward-sexp-func, hs-adjust-block-beginning)
(hs-find-block-beginning-func, hs-find-next-block-func)
(hs-looking-at-block-start-p-func): Set default values to nil.
(hs-adjust-block-end, hs-treesit-things): New buffer-local
variables.
(hs--get-mode-value): New function.
(hs-grok-mode-type): Rewrite.
* lisp/progmodes/f90.el (hs-special-modes-alist):
* lisp/progmodes/fortran.el (hs-special-modes-alist):
* lisp/progmodes/icon.el (icon-mode):
* lisp/progmodes/lua-mode.el (lua-mode):
* lisp/progmodes/python.el (python-base-mode):
* lisp/progmodes/verilog-mode.el (verilog-mode):
* lisp/progmodes/vhdl-mode.el (vhdl-hs-minor-mode): Rewrite
settings.
* lisp/progmodes/python.el (python-hideshow-find-next-block):
New function.
* lisp/treesit.el (treesit-hs-block-end)
(treesit-hs-find-block-beginning, treesit-hs-find-next-block)
(treesit-hs-looking-at-block-start-p): Minor updates.
---
 lisp/progmodes/f90.el          |  12 +--
 lisp/progmodes/fortran.el      |  12 +--
 lisp/progmodes/hideshow.el     | 149 ++++++++++++++++++++++-----------
 lisp/progmodes/icon.el         |  12 +--
 lisp/progmodes/lua-mode.el     |  10 +--
 lisp/progmodes/python.el       |  37 ++++++--
 lisp/progmodes/verilog-mode.el |  12 +--
 lisp/progmodes/vhdl-mode.el    |  10 +--
 lisp/textmodes/mhtml-mode.el   |   2 +-
 lisp/treesit.el                |  99 +++++++++++-----------
 10 files changed, 216 insertions(+), 139 deletions(-)

diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index 96626600d55..c3158069dcd 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -930,7 +930,7 @@ f90-end-block-re
                         "block" "critical") t)
           "\\_>")
   "Regexp matching the end of an F90 \"block\", from the line start.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
 ;; Ignore the fact that FUNCTION, SUBROUTINE, WHERE, FORALL have a
 ;; following "(".  DO, CASE, IF can have labels.
@@ -966,12 +966,12 @@ f90-start-block-re
   "Regexp matching the start of an F90 \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the F90 entry in `hs-special-modes-alist'.")
+Used in the F90 entry in `hs-modes-alist'.")
 
-;; hs-special-modes-alist is autoloaded.
-(add-to-list 'hs-special-modes-alist
-             `(f90-mode ,f90-start-block-re ,f90-end-block-re
-                        "!" f90-end-of-block nil))
+;; hs-modes-alist is autoloaded.
+(add-to-list 'hs-modes-alist
+             `(f90-mode (start . ,f90-start-block-re) (end . ,f90-end-block-re)
+                        (c-start . "!") (forward-fn . f90-end-of-block)))
 
 
 ;; Imenu support.
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index d1f14fdf8fe..6eb75af01a3 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -549,7 +549,7 @@ fortran-end-block-re
           "\\|!\\|$\\)")
   "Regexp matching the end of a Fortran \"block\", from the line start.
 Note that only ENDDO is handled for the end of a DO-loop.  Used
-in the Fortran entry in `hs-special-modes-alist'.")
+in the Fortran entry in `hs-modes-alist'.")
 
 (defconst fortran-start-block-re
   (concat
@@ -582,11 +582,11 @@ fortran-start-block-re
   "Regexp matching the start of a Fortran \"block\", from the line start.
 A simple regexp cannot do this in fully correct fashion, so this
 tries to strike a compromise between complexity and flexibility.
-Used in the Fortran entry in `hs-special-modes-alist'.")
+Used in the Fortran entry in `hs-modes-alist'.")
 
-(add-to-list 'hs-special-modes-alist
-             `(fortran-mode ,fortran-start-block-re ,fortran-end-block-re
-                            "^[cC*!]" fortran-end-of-block nil))
+(add-to-list 'hs-modes-alist
+             `(fortran-mode (start . ,fortran-start-block-re) (end . ,fortran-end-block-re)
+                            (c-start . "^[cC*!]") (forward-fn . fortran-end-of-block)))
 
 
 (defvar fortran-mode-syntax-table
@@ -1247,7 +1247,7 @@ fortran-looking-at-if-then
           (goto-char i)
           (= (line-beginning-position) p)))))
 
-;; Used in hs-special-modes-alist.
+;; Used in hs-modes-alist.
 (defun fortran-end-of-block (&optional num)
   "Move point forward to the end of the current code block.
 With optional argument NUM, go forward that many balanced blocks.
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index 6158253ee53..69fd9bc90f9 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -370,30 +370,39 @@ hs-indicator-show
   :version "31.1")
 
 ;;;###autoload
-(defvar hs-special-modes-alist
-  ;; FIXME: Currently the check is made via
-  ;; (assoc major-mode hs-special-modes-alist) so it doesn't pay attention
-  ;; to the mode hierarchy.
-  '((c-mode "{" "}" "/[*/]" nil nil)
-    (c-ts-mode "{" "}" "/[*/]" nil nil)
-    (c++-mode "{" "}" "/[*/]" nil nil)
-    (c++-ts-mode "{" "}" "/[*/]" nil nil)
-    (bibtex-mode ("@\\S(*\\(\\s(\\)" 1))
-    (java-mode "{" "}" "/[*/]" nil nil)
-    (java-ts-mode "{" "}" "/[*/]" nil nil)
-    (js-mode "{" "}" "/[*/]" nil)
-    (js-ts-mode "{" "}" "/[*/]" nil)
-    (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil)
+(defvar hs-special-modes-alist nil)
+(make-obsolete-variable 'hs-special-modes-alist 'hs-modes-alist "31.1")
+
+;;;###autoload
+(defvar hs-modes-alist
+  '((c-mode    (start . "{") (end . "}") (c-start . "/[*/]"))
+    (c++-mode  (start . "{") (end . "}") (c-start . "/[*/]"))
+    (java-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (bibtex-mode  (start . ("@\\S(*\\(\\s(\\)" 1)))
+    (js-base-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (sgml-mode (start . "<!--\\|<[^/>]*[^/]>") (end . "-->\\|</[^/>]*[^/]>")
+               (c-start . "<!--") (forward-fn . sgml-skip-tag-forward))
+    (html-mode (start . "{\\|<[^/>]*?") (end . "}\\|</[^/>]*[^/]>"))
+    (mhtml-mode (forward-fn . mhtml-forward))
     ;; Add more support here.
     )
   "Alist for initializing the hideshow variables for different modes.
-Each element has the form
-  (MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC
-   FIND-BLOCK-BEGINNING-FUNC FIND-NEXT-BLOCK-FUNC
-   LOOKING-AT-BLOCK-START-P-FUNC).
+Each element is an alist with any of the cons-cells forms:
+ (MODE &optional
+       (start . START)
+       (end . END)
+       (c-start . COMMENT-START)
+       (forward-fn . FORWARD-SEXP-FUNC)
+       (adjust-beg-fn . ADJUST-BEG-FUNC)
+       (adjust-end-fn . ADJUST-END-FUNC)
+       (find-beg-fn . FIND-BLOCK-BEGINNING-FUNC)
+       (find-next-fn . FIND-NEXT-BLOCK-FUNC)
+       (look-start-fn . LOOKING-AT-BLOCK-START-P-FUNC)
+       (treesit-things . TREESIT-THINGS))
 
 If non-nil, hideshow will use these values as regexps to define blocks
-and comments, respectively for major mode MODE.
+and comments, respectively for major mode MODE or current major mode
+parents.
 
 START, END and COMMENT-START are regular expressions.  A block is
 defined as text surrounded by START and END.
@@ -403,7 +412,7 @@ hs-special-modes-alist
 MDATA-SELECTOR an integer that specifies which sub-match is the proper
 place to adjust point, before calling `hs-forward-sexp-func'.  Point
 is adjusted to the beginning of the specified match.  For example,
-see the `hs-special-modes-alist' entry for `bibtex-mode'.
+see the `hs-modes-alist' entry for `bibtex-mode'.
 
 For some major modes, `forward-sexp' does not work properly.  In those
 cases, FORWARD-SEXP-FUNC specifies another function to use instead.
@@ -411,6 +420,9 @@ hs-special-modes-alist
 See the documentation for `hs-adjust-block-beginning' to see what is the
 use of ADJUST-BEG-FUNC.
 
+See the documentation for `hs-adjust-block-end' to see what is the
+use of ADJUST-END-FUNC.
+
 See the documentation for `hs-find-block-beginning-func' to see
 what is the use of FIND-BLOCK-BEGINNING-FUNC.
 
@@ -420,9 +432,12 @@ hs-special-modes-alist
 See the documentation for `hs-looking-at-block-start-p-func' to
 see what is the use of LOOKING-AT-BLOCK-START-P-FUNC.
 
-If any of the elements is left nil or omitted, hideshow tries to guess
-appropriate values.  The regexps should not contain leading or trailing
-whitespace.  Case does not matter.")
+TREESIT-THINGS is a list of treesit things to determine if current block
+at point is valid, see `treesit-thing-at' to get more information about.
+
+If any of the elements in the cons-cell is left nil or omitted, hideshow
+tries to guess appropriate values.  The regexps should not contain
+leading or trailing whitespace.  Case does not matter.")
 
 (defvar hs-hide-all-non-comment-function nil
   "Function called if non-nil when doing `hs-hide-all' for non-comments.")
@@ -548,7 +563,7 @@ hs-block-start-mdata-select
 (defvar-local hs-block-end-regexp nil
   "Regexp for end of block.")
 
-(defvar-local hs-forward-sexp-func #'forward-sexp
+(defvar-local hs-forward-sexp-func nil
   "Function used to do a `forward-sexp'.
 Should change for Algol-ish modes.  For single-character block
 delimiters -- ie, the syntax table regexp for the character is
@@ -556,7 +571,7 @@ hs-forward-sexp-func
 `forward-sexp'.  For other modes such as simula, a more specialized
 function is necessary.")
 
-(defvar-local hs-adjust-block-beginning #'identity
+(defvar-local hs-adjust-block-beginning nil
   "Function used to tweak the block beginning.
 The block is hidden from the position returned by this function,
 as opposed to hiding it from the position returned when searching
@@ -576,7 +591,16 @@ hs-adjust-block-beginning
 
 See `hs-c-like-adjust-block-beginning' for an example of using this.")
 
-(defvar-local hs-find-block-beginning-func #'hs-find-block-beginning
+(defvar-local hs-adjust-block-end nil
+  "Function used to tweak the block end.
+This is useful to ensure some characters such as parenthesis or curly
+braces get properly hidden in python-like modes.
+
+It is called with 1 argument which is the hiding beginning position.
+
+It should return the position from where the hiding ends.")
+
+(defvar-local hs-find-block-beginning-func nil
   "Function used to do `hs-find-block-beginning'.
 It should reposition point at the beginning of the current block
 and return point, or nil if original point was not in a block.
@@ -585,7 +609,7 @@ hs-find-block-beginning-func
 Python, where regexp search and `syntax-ppss' check is not enough
 to find the beginning of the current block.")
 
-(defvar-local hs-find-next-block-func #'hs-find-next-block
+(defvar-local hs-find-next-block-func nil
   "Function used to do `hs-find-next-block'.
 It should reposition point at next block start.
 
@@ -601,7 +625,7 @@ hs-find-next-block-func
 Python, where regexp search is not enough to find the beginning
 of the next block.")
 
-(defvar-local hs-looking-at-block-start-p-func #'hs-looking-at-block-start-p
+(defvar-local hs-looking-at-block-start-p-func nil
   "Function used to do `hs-looking-at-block-start-p'.
 It should return non-nil if the point is at the block start.
 
@@ -612,6 +636,9 @@ hs-looking-at-block-start-p-func
 (defvar-local hs-inside-comment-p-func nil
   "Function used to check if point is inside a comment.")
 
+(defvar-local hs-treesit-things nil
+  "List of treesit things to check if point is at a valid block.")
+
 (defvar hs-headline nil
   "Text of the line where a hidden block begins, set during isearch.
 You can display this in the mode line by adding the symbol `hs-headline'
@@ -703,8 +730,7 @@ hs-block-positions
           ;; `block-start' is the point at the end of the block
           ;; beginning, which may need to be adjusted
           (save-excursion
-            (goto-char (funcall (or hs-adjust-block-beginning #'identity)
-                                header-end))
+            (goto-char (funcall hs-adjust-block-beginning header-end))
             (setq block-beg (line-end-position)))
           ;; `block-end' is the point at the end of the block
           (hs-forward-sexp mdata 1)
@@ -716,7 +742,8 @@ hs-block-positions
                        (funcall hs-block-end-regexp)
                        (match-beginning 0))
                       (t (point))))
-          (cons block-beg block-end))))))
+          (cons block-beg
+                (or (funcall hs-adjust-block-end block-beg) block-end)))))))
 
 (defun hs--make-indicators-overlays (beg)
   "Helper function to make the indicators overlays."
@@ -987,16 +1014,30 @@ hs-inside-comment-p--default
           (when (>= (point) q)
             (list (and hideable p) (point))))))))
 
+(defun hs--get-mode-value (value &optional old-nth)
+  "Get VALUE for current major mode in `hs-modes-alist'.
+OLD-NTH is only for backward compatibility with `hs-special-modes-alist'."
+  (if-let* (old-nth
+            (old-lookup (assoc major-mode hs-special-modes-alist)))
+      (nth old-nth old-lookup)
+    (catch 'hs-grok-exit
+      (dolist (modes (get major-mode 'derived-mode--all-parents))
+        ;; If we cannot find VALUE in in current MODES, try to find it in
+        ;; the next mode in MODES
+        (if-let* ((list (assoc modes hs-modes-alist))
+                  (elm (alist-get value list)))
+            (throw 'hs-grok-exit elm))))))
+
 (defun hs-grok-mode-type ()
   "Set up hideshow variables for new buffers.
-If `hs-special-modes-alist' has information associated with the
+If `hs-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 (bound-and-true-p comment-start)
            (bound-and-true-p comment-end))
-      (let* ((lookup (assoc major-mode hs-special-modes-alist))
-             (start-elem (or (nth 1 lookup) "\\s(")))
+      (let ((start-elem (or (hs--get-mode-value 'start 1) "\\s(")))
+
         (if (listp start-elem)
             ;; handle (START-REGEXP MDATA-SELECT)
             (setq hs-block-start-regexp (car start-elem)
@@ -1004,23 +1045,39 @@ hs-grok-mode-type
           ;; 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)
+
+        (setq hs-block-end-regexp (or hs-block-end-regexp
+                                      (hs--get-mode-value 'end 2)
+                                      "\\s)")
+              hs-c-start-regexp (or hs-c-start-regexp
+                                    (hs--get-mode-value 'c-start 3)
                                     (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 (or (nth 5 lookup) #'identity)
-              hs-find-block-beginning-func (or (nth 6 lookup)
+              hs-forward-sexp-func (or hs-forward-sexp-func
+                                       (hs--get-mode-value 'forward-fn 4)
+                                       #'forward-sexp)
+              hs-adjust-block-beginning (or hs-adjust-block-beginning
+                                            (hs--get-mode-value 'adjust-fn 5)
+                                            #'identity)
+              hs-adjust-block-end (or hs-adjust-block-end
+                                      (hs--get-mode-value 'adjust-end-fn 5)
+                                      #'ignore)
+              hs-find-block-beginning-func (or hs-find-block-beginning-func
+                                               (hs--get-mode-value 'find-beg-fn 6)
                                                #'hs-find-block-beginning)
-              hs-find-next-block-func (or (nth 7 lookup)
+              hs-find-next-block-func (or hs-find-next-block-func
+                                          (hs--get-mode-value 'find-next-fn 7)
                                           #'hs-find-next-block)
-              hs-looking-at-block-start-p-func
-              (or (nth 8 lookup)
-                  #'hs-looking-at-block-start-p)))
+              hs-looking-at-block-start-p-func (or hs-looking-at-block-start-p-func
+                                                   (hs--get-mode-value 'look-start-fn 8)
+                                                   #'hs-looking-at-block-start-p)
+              hs-treesit-things (or hs-treesit-things
+                                    (hs--get-mode-value 'treesit-things)
+                                    'list)))
     (setq hs-minor-mode nil)
     (error "%s Mode doesn't support Hideshow Minor Mode"
            (format-mode-line mode-name))))
@@ -1341,10 +1398,8 @@ hs-minor-mode
   (setq hs-headline nil)
   (if hs-minor-mode
       (progn
-        ;; Use such heuristics that if one buffer-local variable
-        ;; is already defined, don't overwrite other variables too.
-        (unless (buffer-local-value 'hs-inside-comment-p-func (current-buffer))
-          (hs-grok-mode-type))
+        ;; Set the variables according to `hs-modes-alist'.
+        (hs-grok-mode-type)
         ;; Turn off this mode if we change major modes.
         (add-hook 'change-major-mode-hook
                   #'turn-off-hideshow
diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el
index dee57956ce7..2a5172609d9 100644
--- a/lisp/progmodes/icon.el
+++ b/lisp/progmodes/icon.el
@@ -167,12 +167,12 @@ icon-mode
   ;; imenu support
   (setq-local imenu-generic-expression icon-imenu-generic-expression)
   ;; hideshow support
-  ;; we start from the assertion that `hs-special-modes-alist' is autoloaded.
-  (unless (assq 'icon-mode hs-special-modes-alist)
-    (setq hs-special-modes-alist
-	  (cons '(icon-mode  "\\<procedure\\>" "\\<end\\>" nil
-			     icon-forward-sexp-function)
-		hs-special-modes-alist))))
+  ;; we start from the assertion that `hs-modes-alist' is autoloaded.
+  (unless (assq 'icon-mode hs-modes-alist)
+    (setq hs-modes-alist
+	  (cons '(icon-mode  (start . "\\<procedure\\>") (end . "\\<end\\>")
+                             (forward-fn . icon-forward-sexp-function))
+		hs-modes-alist))))
 
 ;; This is used by indent-for-comment to decide how much to
 ;; indent a comment in Icon code based on its context.
diff --git a/lisp/progmodes/lua-mode.el b/lisp/progmodes/lua-mode.el
index 01d91637cf0..07b3777c988 100644
--- a/lisp/progmodes/lua-mode.el
+++ b/lisp/progmodes/lua-mode.el
@@ -553,12 +553,12 @@ lua-mode
   (add-hook 'flymake-diagnostic-functions #'lua-flymake nil t)
 
   ;; Hide-show setup
-  (unless (assq 'lua-mode hs-special-modes-alist)
-    (add-to-list 'hs-special-modes-alist
+  (unless (assq 'lua-mode hs-modes-alist)
+    (add-to-list 'hs-modes-alist
                  `(lua-mode
-                   ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words) ; Start
-                   ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words) ; End
-                   nil lua-forward-sexp))))
+                   (start . ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words)) ; Start
+                   (end . ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words)) ; End
+                   (forward-fn . lua-forward-sexp)))))
 
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 5a96972caa7..e1df123d172 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -5912,6 +5912,20 @@ python-hideshow-find-next-block
         (beginning-of-line)
         (looking-at regexp)))))
 
+(defun python-ts-adjust-block-end-fn (block-beg)
+  "Python-ts-mode specific `hs-adjust-block-end' function for `hs-minor-mode'.
+
+BLOCK-BEG is the beginning position where the hiding will be performed.
+
+This is only used to ensure the block end position in function
+definitions and parens."
+  (unless (save-excursion
+            (goto-char block-beg)
+            (treesit-thing-at
+             (if (bobp) (point) (1- (point)))
+             '(or "argument_list" (and anonymous "\\`[](),[{}]\\'"))))
+    (line-end-position)))
+
 
 ;;; Imenu
 
@@ -7342,18 +7356,23 @@ python-base-mode
   ;; TODO: Use tree-sitter to figure out the block in `python-ts-mode'.
   (dolist (mode '(python-mode python-ts-mode))
     (add-to-list
-     'hs-special-modes-alist
+     'hs-modes-alist
      `(,mode
-       ,python-nav-beginning-of-block-regexp
+       (start . ,python-nav-beginning-of-block-regexp)
        ;; Use the empty string as end regexp so it doesn't default to
        ;; "\\s)".  This way parens at end of defun are properly hidden.
-       ""
-       "#"
-       python-hideshow-forward-sexp-function
-       nil
-       python-nav-beginning-of-block
-       python-hideshow-find-next-block
-       python-info-looking-at-beginning-of-block)))
+       (end . "")
+       (c-start . "#")
+       (forward-fn . python-hideshow-forward-sexp-function)
+       (find-beg-fn . python-nav-beginning-of-block)
+       (find-next-fn . python-hideshow-find-next-block)
+       (look-start-fn . python-info-looking-at-beginning-of-block)
+       (treesit-things . (or defun sexp)))))
+
+  (add-to-list
+   'hs-modes-alist
+   '(python-ts-mode
+     (adjust-end-fn . python-ts-adjust-block-end-fn)))
 
   (setq-local outline-regexp (python-rx (* space) block-start))
   (setq-local outline-level
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 2f5525786e1..81fecec806f 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -4363,12 +4363,12 @@ verilog-mode
   (when (and (boundp 'which-func-modes) (listp which-func-modes))
     (add-to-list 'which-func-modes 'verilog-mode))
   ;; hideshow support
-  (when (boundp 'hs-special-modes-alist)
-    (unless (assq 'verilog-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-            (cons '(verilog-mode "\\<begin\\>" "\\<end\\>" nil
-                                 verilog-forward-sexp-function)
-                  hs-special-modes-alist))))
+  (when (boundp 'hs-modes-alist)
+    (unless (assq 'verilog-mode hs-modes-alist)
+      (setq hs-modes-alist
+            (cons '(verilog-mode (beg . "\\<begin\\>") (end . "\\<end\\>")
+                                 (forward-fn . verilog-forward-sexp-function))
+                  hs-modes-alist))))
 
   (add-hook 'completion-at-point-functions
             #'verilog-completion-at-point nil 'local)
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 593a83ceffa..82e6f41e07e 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -13282,11 +13282,11 @@ vhdl-hs-minor-mode
   (if (not (boundp 'hs-block-start-mdata-select))
       (vhdl-warning-when-idle "Install included `hideshow.el' patch first (see INSTALL file)")
     ;; initialize hideshow
-    (unless (assoc 'vhdl-mode hs-special-modes-alist)
-      (setq hs-special-modes-alist
-	    (cons (list 'vhdl-mode vhdl-hs-start-regexp nil "--\\( \\|$\\)"
-			'vhdl-hs-forward-sexp-func nil)
-		  hs-special-modes-alist)))
+    (unless (assoc 'vhdl-mode hs-modes-alist)
+      (setq hs-modes-alist
+	    (cons `(vhdl-mode (start . ,vhdl-hs-start-regexp) (c-start . "--\\( \\|$\\)")
+			      (forward-fn . vhdl-hs-forward-sexp-func))
+		  hs-modes-alist)))
     (if (featurep 'xemacs) (make-local-hook 'hs-minor-mode-hook))
     (if vhdl-hide-all-init
 	(add-hook 'hs-minor-mode-hook #'hs-hide-all nil t)
diff --git a/lisp/textmodes/mhtml-mode.el b/lisp/textmodes/mhtml-mode.el
index e1ea73dc9ac..4ab560df6a8 100644
--- a/lisp/textmodes/mhtml-mode.el
+++ b/lisp/textmodes/mhtml-mode.el
@@ -306,7 +306,7 @@ mhtml--flyspell-check-word
         (flyspell-generic-progmode-verify)
       t)))
 
-;; Support for hideshow.el (see `hs-special-modes-alist').
+;; Support for hideshow.el (see `hs-modes-alist').
 (defun mhtml-forward (arg)
   "Move point forward past a structured expression.
 If point is on a tag, move to the end of the tag.
diff --git a/lisp/treesit.el b/lisp/treesit.el
index a8a515c434d..717472b58fd 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -4230,65 +4230,68 @@ treesit-outline-level
 
 (defun treesit-hs-block-end ()
   "Tree-sitter implementation of `hs-block-end-regexp'."
-  (let* ((pred 'list)
-         (thing (treesit-thing-at
-                 (if (bobp) (point) (1- (point))) pred))
-         (end (when thing (treesit-node-end thing)))
-         (last (when thing (treesit-node-child thing -1)))
-         (beg (if last (treesit-node-start last)
-                (if (bobp) (point) (1- (point))))))
-    (when (and thing (eq (point) end))
-      (set-match-data (list beg end))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((thing (treesit-thing-at
+                   (if (bobp) (point) (1- (point))) hs-treesit-things))
+           (end (when thing (treesit-node-end thing)))
+           (last (when thing (treesit-node-child thing -1)))
+           (beg (if last (treesit-node-start last)
+                  (if (bobp) (point) (1- (point))))))
+      (when (and thing (eq (point) end))
+        (set-match-data (list beg end))
+        t))))
 
 (defun treesit-hs-find-block-beginning ()
   "Tree-sitter implementation of `hs-find-block-beginning-func'."
-  (let* ((pred 'list)
-         (thing (treesit-thing-at (point) pred))
-         (beg (when thing (treesit-node-start thing)))
-         (end (when beg (min (1+ beg) (point-max)))))
-    (when thing
-      (goto-char beg)
-      (set-match-data (list beg end))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((thing (treesit-thing-at (point) hs-treesit-things))
+           (beg (when thing (treesit-node-start thing)))
+           (end (when beg (min (1+ beg) (point-max)))))
+      (when thing
+        (goto-char beg)
+        (set-match-data (list beg end))
+        t))))
 
 (defun treesit-hs-find-next-block (_regexp maxp comments)
   "Tree-sitter implementation of `hs-find-next-block-func'."
   (when (not comments)
     (forward-comment (point-max)))
-  (let* ((comment-pred
-          (when comments
-            (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
-                'comment "\\`comment\\'")))
-         (pred (if comment-pred (append '(or list) (list comment-pred)) 'list))
-         ;; `treesit-navigate-thing' can't find a thing at bobp,
-         ;; so use `treesit-thing-at' to match at bobp.
-         (current (treesit-thing-at (point) pred))
-         (beg (or (and current (eq (point) (treesit-node-start current)) (point))
-                  (treesit-navigate-thing (point) 1 'beg pred)))
-         ;; Check if we found a list or a comment
-         (list-thing (when beg (treesit-thing-at beg 'list)))
-         (comment-thing (when beg (treesit-thing-at beg comment-pred)))
-         (comment-p (and comment-thing (eq beg (treesit-node-start comment-thing))))
-         (thing (if comment-p comment-thing list-thing))
-         (end (if thing (min (1+ (treesit-node-start thing)) (point-max)))))
-    (when (and end (<= end maxp))
-      (goto-char end)
-      (set-match-data
-       (if (and comments comment-p)
-           (list beg end nil nil beg end)
-         (list beg end beg end)))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((comment-pred
+            (when comments
+              (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
+                  'comment "\\`comment\\'")))
+           (pred (if comment-pred
+                     (append `(or ,hs-treesit-things) (list comment-pred))
+                   hs-treesit-things))
+           ;; `treesit-navigate-thing' can't find a thing at bobp,
+           ;; so use `treesit-thing-at' to match at bobp.
+           (current (treesit-thing-at (point) pred))
+           (beg (or (and current (eq (point) (treesit-node-start current)) (point))
+                    (treesit-navigate-thing (point) 1 'beg pred)))
+           ;; Check if we found a block or a comment
+           (block-thing (when beg (treesit-thing-at beg hs-treesit-things)))
+           (comment-thing (when beg (treesit-thing-at beg comment-pred)))
+           (comment-p (and comment-thing (eq beg (treesit-node-start comment-thing))))
+           (thing (if comment-p comment-thing block-thing))
+           (end (if thing (min (1+ (treesit-node-start thing)) (point-max)))))
+      (when (and end (<= end maxp))
+        (goto-char end)
+        (set-match-data
+         (if (and comments comment-p)
+             (list beg end nil nil beg end)
+           (list beg end beg end)))
+        t))))
 
 (defun treesit-hs-looking-at-block-start-p ()
   "Tree-sitter implementation of `hs-looking-at-block-start-p-func'."
-  (let* ((pred 'list)
-         (thing (treesit-thing-at (point) pred))
-         (beg (when thing (treesit-node-start thing)))
-         (end (min (1+ (point)) (point-max))))
-    (when (and thing (eq (point) beg))
-      (set-match-data (list beg end))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((thing (treesit-thing-at (point) hs-treesit-things))
+           (beg (when thing (treesit-node-start thing)))
+           (end (min (1+ (point)) (point-max))))
+      (when (and thing (eq (point) beg))
+        (set-match-data (list beg end))
+        t))))
 
 (defun treesit-hs-inside-comment-p ()
   "Tree-sitter implementation of `hs-inside-comment-p-func'."
-- 
2.51.0


--=-=-=
Content-Type: text/plain


--
- E.G via Gnus and Org.

--=-=-=--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 23 Oct 2025 06:54:29 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Oct 23 02:54:29 2025
Received: from localhost ([127.0.0.1]:59485 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vBpDQ-00027J-Ga
	for submit <at> debbugs.gnu.org; Thu, 23 Oct 2025 02:54:29 -0400
Received: from mout-p-101.mailbox.org ([80.241.56.151]:33306)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vBpD4-00025j-2c
 for 79671 <at> debbugs.gnu.org; Thu, 23 Oct 2025 02:54:06 -0400
Received: from smtp1.mailbox.org (smtp1.mailbox.org
 [IPv6:2001:67c:2050:b231:465::1])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4cscFf0Sg8z9sQV;
 Thu, 23 Oct 2025 08:53:58 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1761202438;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
 in-reply-to:in-reply-to:references:references;
 bh=B5drpa3ddBaVLAMtb4ThIYGwE+GSuCiNVs/mhXpxbec=;
 b=SDKF9LOv0+JbA4UHR/+v+nXAtzDauAIPfnfJmQMYEj+QoF/92ooyDoSQwWrmB1UrF5x3Ln
 1IRUktHJVEVP87MeG0g1r9zZPCOs1PyOKsX7xSVagvqVULrBb5oqf99ljtM7PsqBqL7UYi
 5kdRjUilME3qg6aAx5AM108kxu5GDP5X4RhQyLfWZKHvuqFJcYmfTU1dpCpERcahJWiK7V
 4Ius5FU/aPgg0OseIKibtKp1OY4cSJmMW/7r0mewagLmNN4/uEVs26/qjHzsbyAW3HOv2f
 O3PfFqpj8mxO1LGAeioS3sDRx6WuPwzdwvoP+gxO+AOdb1b+tdhzpGzSvUEBiQ==
Authentication-Results: outgoing_mbo_mout; dkim=none;
 spf=pass (outgoing_mbo_mout: domain of juri@HIDDEN designates
 2001:67c:2050:b231:465::1 as permitted sender) smtp.mailfrom=juri@HIDDEN
From: Juri Linkov <juri@HIDDEN>
To: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79671: (WIP) [PATCH] hideshow: Rewrite
 'hs-special-modes-alist'
In-Reply-To: <87ms5izqi3.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
 <87ms5izqi3.fsf@HIDDEN>
Date: Thu, 23 Oct 2025 09:53:10 +0300
Message-ID: <87347a2kc1.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Rspamd-Queue-Id: 4cscFf0Sg8z9sQV
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

>>> - Support for mode hierarchy 'hs-special-modes-alist'.
>>>
>>> Previously, 'assoc' was used to get the mode and their settings to apply
>>> (as the deleted FIXME in the patch describes it), now it should support
>>> the mode and their parents, thus, just by adding (html-mode ...), it
>>> applies to mhtml-mode and its derivatives.
>>
>> I noticed that in your patch it applies to parents instead of derivatives,
>> since it uses (get major-mode 'derived-mode--all-parents).
>
> It should also apply to the current derived mode.
>
> e.g.  If nxml-mode is not defined in `hs-special-modes-alist`, it will
> try to find a parent mode in `hs-special-modes-alist`.

Sorry, it seems I was mistaken.  By re-reading your patch I see
that it already supports overriding parent settings.  For example,
if the user wants mhtml settings to override html settings,
this will be possible to customize with:

 (setopt hs-special-modes-alist
   '((mhtml-mode <some mhtml-specific settings>)
     (html-mode <some html settings>))

>>> - Change 'hs-special-modes-alist' format.
>>
>> I suppose the old format will still be supported for backward-compatibility?
>
> Yes, but currently it has no effect.  I'm thinking about define a new
> variable as a replacement for 'hs-special-modes-alist', and mark
> 'hs-special-modes-alist' as obsolete but with compatibility.

A new variable with a shorter name like 'hs-modes-alist'
is also a variant indeed.

>>> - Add an easy way to support treesit
>>>
>>> The treesit support in hideshow is partial, some modes (such as
>>> python-ts-mode) do not fully support folding with treesit (e.g. def).
>>
>> Currently hs-minor-mode uses the hard-coded 'list' thing, which
>> e.g. in python-ts-mode doesn't include 'function_definition'
>> for compatibility with python-mode.
>>
>> But to make this configurable, we could add a new thing, e.g. 'hideshow',
>> to be defined in 'treesit-thing-settings' instead of 'hs-special-modes-alist'.
>> Or maybe better to support both.
>
> Was not the 'list' thing designed to be used in hideshow?

The 'list' thing was designed to be used for list-related commands
like 'forward-list', 'backward-list', 'backward-up-list'.
It is a good approximation for blocks in hs-minor-mode, and it
still should fall back to 'list' when no other settings are defined
either by the 'hideshow' thing or in 'hs-special-modes-alist'.

> I prefer 'hs-special-modes-alist', I don't know if defining a derived
> treesit mode from another treesit mode can inherit the 'hideshow' thing,
> having 'hs-special-modes-alist' will ensure this works.

There is some kind of inheritance for treesit-things such as e.g.
'mhtml-ts-mode--treesit-thing-settings' that gets parent's things
and adds its own.

> Also I don't think this should be hardcoded.

Agreed.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 22 Oct 2025 22:24:25 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Oct 22 18:24:25 2025
Received: from localhost ([127.0.0.1]:58214 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vBhFp-0003Vl-C3
	for submit <at> debbugs.gnu.org; Wed, 22 Oct 2025 18:24:25 -0400
Received: from mail-ot1-x343.google.com ([2607:f8b0:4864:20::343]:51378)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vBhFl-0003VW-Jx
 for 79671 <at> debbugs.gnu.org; Wed, 22 Oct 2025 18:24:23 -0400
Received: by mail-ot1-x343.google.com with SMTP id
 46e09a7af769-7c280b71af9so52808a34.2
 for <79671 <at> debbugs.gnu.org>; Wed, 22 Oct 2025 15:24:21 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761171855; x=1761776655; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=qBhY8VLd68zgMQxiUpQ/14IHIrgHCsxVns508tsg3d0=;
 b=d6eiBGMMQWi6WRBAg+9U5RrNtwjJgQ/y5J0xnmYNwCQA7UXN9oRcA0A/phmP9sWaZr
 Egh0T1U3NbV4x9f8hyYwsTX+BR5irLYjGNcTCieKmu+QOTJvb1/zCfFik/lRYxSTcBhx
 GAx+FQMB8tYSMaH3oL/CdVUZNbhepWdDaokyQ1SKsFWWg74JfLH2TS/i2VmTcgdJ7ORi
 CThH3m2BD+7BZiGMNSPX+/3yZDdm5w0Azd1GGQHlEwRTVyWzNrq07Hi2QFalcXw7PInG
 ws9Fk3VwEUVOeSJuN5wRr5IGq9gZuoTB3E+oGD35y6SoYDT0mI0DcajWvF26ilqErSaA
 4RdQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761171855; x=1761776655;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=qBhY8VLd68zgMQxiUpQ/14IHIrgHCsxVns508tsg3d0=;
 b=HTD6GQR44epfV4Pte1ku5F4/TmaPrmymiDuT7OKZzxDft1iXjD30NCVBtqB5IcGiDC
 sNrZJ/k9mjZmgOJJcrOi4rFZAIZcnBZIpFD/TGyZzWgnBxkVxE55Z0aZOsyCfyr6evdK
 pAN3b/qw2wpWAdGSBzJQDVFGvI8inoKMZxcv76qj40nURHGO/rW6ktTh5EoiIsZF8cW8
 UYg0VcKMl9Oh9UEJJOr+w6A9cQvh43LYP4AUb34iVsDGkqsZB8NXr6cfw2EnPbTtnKHi
 3TizPgpwahuHI1TfxntIoeIRCcGZRVE0B+MVxLaYETPe+hUPwaMRHucDOrjv+iHpmaY6
 K5RQ==
X-Gm-Message-State: AOJu0Yx6x+CiEoILUh4KsHkxeSKf2nNFvvW0X3p040WKWd8k+IICchDo
 rU+7qvTJsLRgQax0QV0zxO+eeV3U0wkLZvn7M0CRQWBndWFVG5OwbDNTJ8JhWDIK
X-Gm-Gg: ASbGncu5Uz8h9ecb3EodIHtRkDdtHGBQOUXowGDVA+eMgnC1G2reF2AziDHF2WVbTDY
 ocf97C+PzF8SHUSYeyahOe3SU7N+iGQk7BGvY7Hw5MzqNM+wqn6ElK8AsqvsAnm5l8jqhTB7eQO
 LYkS+zmX8SaXyCsv4JiGYBPh23T6P4vlzN096ST1uk9hU/6I9zAEHGjumkUxp0YIhLYOepyMuAP
 wB+KJJzmUvlzfzyHnFxdjOJzNWWhS41tNs0dqQT3/LPazRBkMh+7gGR9QaHvbSe1Z5mznPUkkr+
 jA2eh81fOxYc2H7E9q3O24SMK7agiX3xHpRHO9TJ9NCE01VjMDPJCZGHyobOZ18BReH+WA00a/A
 CbV1ocjgDnGajm71EAeKZxew+jC5bt37ieIo3TVAy21oEvQJqfEqPHDs70cSRiuEKQiAuVJg2AE
 N3d6+P
X-Google-Smtp-Source: AGHT+IGt4pLORFkoFhOOW9SvRPSsDMPS4Pnz2Kpi4Lf2WdvpERaMrRjjJ3imcQhKFAMmtKeh0+YD7A==
X-Received: by 2002:a05:6808:4f50:b0:43f:b3e0:7959 with SMTP id
 5614622812f47-443a30139b7mr10177874b6e.49.1761171854954; 
 Wed, 22 Oct 2025 15:24:14 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 5614622812f47-44bd44fad99sm73655b6e.26.2025.10.22.15.24.14
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Wed, 22 Oct 2025 15:24:14 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Juri Linkov <juri@HIDDEN>
Subject: Re: bug#79671: (WIP) [PATCH] hideshow: Rewrite
 'hs-special-modes-alist'
In-Reply-To: <87plafs9pa.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87plafs9pa.fsf@HIDDEN>
Date: Wed, 22 Oct 2025 16:24:13 -0600
Message-ID: <87ikg6zib6.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

Juri Linkov <juri@HIDDEN> writes:

>> - Change 'hs-special-modes-alist' format.

[...]

> I suppose the old format will still be supported for backward-compatibility?

Yes, but currently it has no effect.  I'm thinking about define a new
variable as a replacement for 'hs-special-modes-alist', and mark
'hs-special-modes-alist' as obsolete but with compatibility.

>> - Add an easy way to support treesit
>>
>> The treesit support in hideshow is partial, some modes (such as
>> python-ts-mode) do not fully support folding with treesit (e.g. def).
>
> Currently hs-minor-mode uses the hard-coded 'list' thing, which
> e.g. in python-ts-mode doesn't include 'function_definition'
> for compatibility with python-mode.
>
> But to make this configurable, we could add a new thing, e.g. 'hideshow',
> to be defined in 'treesit-thing-settings' instead of 'hs-special-modes-alist'.
> Or maybe better to support both.

Was not the 'list' thing designed to be used in hideshow?

I prefer 'hs-special-modes-alist', I don't know if defining a derived
treesit mode from another treesit mode can inherit the 'hideshow' thing,
having 'hs-special-modes-alist' will ensure this works.

Also I don't think this should be hardcoded.

-- 
- E.G via Gnus and Org.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 22 Oct 2025 19:27:28 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Oct 22 15:27:28 2025
Received: from localhost ([127.0.0.1]:57943 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vBeUa-0002cB-86
	for submit <at> debbugs.gnu.org; Wed, 22 Oct 2025 15:27:28 -0400
Received: from mail-ot1-x342.google.com ([2607:f8b0:4864:20::342]:58443)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vBeUX-0002bn-96
 for 79671 <at> debbugs.gnu.org; Wed, 22 Oct 2025 15:27:26 -0400
Received: by mail-ot1-x342.google.com with SMTP id
 46e09a7af769-7c2823c3475so32436a34.0
 for <79671 <at> debbugs.gnu.org>; Wed, 22 Oct 2025 12:27:25 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761161238; x=1761766038; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=0ZMXZhU3cV6mOXN+8+ykfmls9Ukv059oWJqpa//CVck=;
 b=XtAmqUiHkPX11aL5/A3Zsrtl9IpC8DgcCLBImibWOPNlZ+xKkiiv4Kb+MBwInmUWqd
 l2LsDmItKv4x0SsnWfJufvNRA4MNlCvm3B/PA9AoFmoA6jBUYKZZQjKvR88wCCg+P9pa
 AcQ+guCum41ccKeqluPZVATrD4NI95u7Ye71sNdUUP6SmzdNQ9qMAVQ8wqCoU7w+kx6C
 mZw5b/A7iLAsWyD7Bkhsop2CSTokHagjuimRKXMiuJH7p4K7WWWHwskBaGA4nRCWHYLs
 bQ5YdR3iz42nhnakEYwkR4m0UY49K6UuQoPN6eLhzb15jV2/O2b/SF/207aezmpysMx3
 g8eA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761161238; x=1761766038;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=0ZMXZhU3cV6mOXN+8+ykfmls9Ukv059oWJqpa//CVck=;
 b=KTwFqnfEJ0hXIhzfGrtzmsizFYiH5xEFJR/TLpknqoy9fQoARruqLvGxrb/rCwDrhw
 gx4oyseA/hSObHtuNLHympQYb9B09hpRxQkLpV6lWeX+6zFWztygSwbGOCCCkIumEi/a
 ECyjvs8PP7dgJHQacOyGKB7XVh7m6+t29Lsj/f9fYI2f1q8VJxqmsiu0wKcrzyvXJH+M
 L3tWe6U5cHwW5oUtpxt2rNEQoQumzNVz6cMDQl6WkLvJvObxU87+1mx0GLk06+la2hVz
 4al22DOTPpUjG54j5m6XQmWv47fEaSqvkXuMBDQ3YPJeucvE7KI3sahc5tT8YmhxbGDY
 HPSg==
X-Gm-Message-State: AOJu0Yx3j99hMCQrB/EVys68PmtgqaDvT66o3VhOzDR8E/j0MuTi+oSV
 ynK71knKxJT+jBQMwqV4St+JD0tkK5ujkqkr0ZaP2Ol1Uc7ttisfJlqr/NHVqD0x
X-Gm-Gg: ASbGnctS4U5gsCa18Dr8zhn3z8kTyRkax8Dv0tNzKaAgYTp/lxBWOQIhKIdhGXLaFlX
 kLwpv/MFMBlU/04udaXN+V+aS5LJfx387U9leZBJIR05OQDGqwcbHpFduf0M4YWvluj+FZu/8u4
 XReAQ0oaOLYHMmmYj2hsyx2hmdEF7WNWtXKaZHnoed+LUVjiW08sM17EL4Hi9T6RG33glz8TUiW
 puHhlU8sOqZmlpcdlgT+kKe4tZS8YpJ7MEj8CFGM6StUVlxEJGaPcyupS2jOJhIpeHTmPYdLK6V
 6JD80A1bCO8jM2wsI/bIKoojrjPPfsEFD3YjIqfK9L9O7o7+jaTlKQ9J5nsGq8PhkB5CndIjLR9
 jQtP41jr4CXQbV2tm0IXsZ7wy7vSpXj0sc5WsvtiGEfr9O69qRLQ59tuSUwWxg6GhmKeJJ6YLrY
 fT4kMDbxPlQ1MfGss=
X-Google-Smtp-Source: AGHT+IGv/5C9gOUAJMBi4FTOt2KyhQLaCCHSVWeZ/7sA/yBGxT13kF9uQqJLTe6R+AslphaQdGlNXQ==
X-Received: by 2002:a05:6808:1b0f:b0:438:399b:a894 with SMTP id
 5614622812f47-443a2ff48a3mr8637085b6e.44.1761161238460; 
 Wed, 22 Oct 2025 12:27:18 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 46e09a7af769-7c3e326dfb3sm788378a34.32.2025.10.22.12.27.17
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Wed, 22 Oct 2025 12:27:17 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Juri Linkov <juri@HIDDEN>
Subject: Re: bug#79671: (WIP) [PATCH] hideshow: Rewrite
 'hs-special-modes-alist'
In-Reply-To: <87qzuv6ij6.fsf@HIDDEN>
References: <87ecqvx0a9.fsf@HIDDEN> <87qzuv6ij6.fsf@HIDDEN>
Date: Wed, 22 Oct 2025 13:27:16 -0600
Message-ID: <87ms5izqi3.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

Juri Linkov <juri@HIDDEN> writes:

>> - Support for mode hierarchy 'hs-special-modes-alist'.
>>
>> Previously, 'assoc' was used to get the mode and their settings to apply
>> (as the deleted FIXME in the patch describes it), now it should support
>> the mode and their parents, thus, just by adding (html-mode ...), it
>> applies to mhtml-mode and its derivatives.
>
> I noticed that in your patch it applies to parents instead of derivatives,
> since it uses (get major-mode 'derived-mode--all-parents).

It should also apply to the current derived mode.

e.g.  If nxml-mode is not defined in `hs-special-modes-alist`, it will
try to find a parent mode in `hs-special-modes-alist`.

>> +       (start . START)
>> +       (end . END)
>> +       (c-start . COMMENT-START)
>> +       (fsexp-fn . FORWARD-SEXP-FUNC)
>> +       (aj-beg-fn . ADJUST-BEG-FUNC)
>> +       (find-beg-fn . FIND-BLOCK-BEGINNING-FUNC)
>> +       (find-next-fn . FIND-NEXT-BLOCK-FUNC)
>> +       (look-start-fn . LOOKING-AT-BLOCK-START-P-FUNC)
>> +       (treesit-things . TREESIT-THINGS))
>
> Most shorthands are self-explanatory, except "fsexp-fn" and "aj-beg-fn".
> Better and less confusing names but still short would be for example:
>
>           (forward-fn . FORWARD-SEXP-FUNC)
>           (adjust-fn . ADJUST-BEG-FUNC)

Thanks, I've renamed them now.

-- 
- E.G via Gnus and Org.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 22 Oct 2025 16:14:52 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Oct 22 12:14:52 2025
Received: from localhost ([127.0.0.1]:57504 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vBbUC-0008Or-3p
	for submit <at> debbugs.gnu.org; Wed, 22 Oct 2025 12:14:52 -0400
Received: from mout-p-103.mailbox.org ([2001:67c:2050:0:465::103]:33044)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vBbU9-0008OC-El
 for 79671 <at> debbugs.gnu.org; Wed, 22 Oct 2025 12:14:50 -0400
Received: from smtp2.mailbox.org (smtp2.mailbox.org
 [IPv6:2001:67c:2050:b231:465::2])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by mout-p-103.mailbox.org (Postfix) with ESMTPS id 4csDl54pGRz9scY;
 Wed, 22 Oct 2025 18:14:41 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1761149681;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
 in-reply-to:in-reply-to:references:references;
 bh=Hkmbk5CLjxDu8aTe88+op25ZEFLat6DWZ66iJ5Ed57Q=;
 b=rPrIGMDBf+NAM9VVvqnKuqbMqvmImVxw6zwOlpltC82awhb1+dQbnroB1uYnAb7Am3feiB
 4Tuu4MoprWBIJksKS6/0c9b7MOUaEYDlhNrF72z2Tr7nwsb1Bg3tTH5vxFeg9CVE3Zx4cm
 E+xFscICQjSGn7Fa3E7mi6kN1NI2d8VK4WSj4XUL8skrVO17OLLBrO1udh7ok6D1ix6iMD
 yc3gIVUiYa+/AwRlWUHARvXs9163/Yb4w3s3l3H+jooxurCYoHZrH+rKcJadnZeiEIuRdK
 UMmPpNIwmis3NJpEtlbglfMACsyY3RJKuhGXsfAm41m6RiolfPAJjH4y89OnTQ==
Authentication-Results: outgoing_mbo_mout; dkim=none;
 spf=pass (outgoing_mbo_mout: domain of juri@HIDDEN designates
 2001:67c:2050:b231:465::2 as permitted sender) smtp.mailfrom=juri@HIDDEN
From: Juri Linkov <juri@HIDDEN>
To: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79671: (WIP) [PATCH] hideshow: Rewrite
 'hs-special-modes-alist'
In-Reply-To: <87ecqvx0a9.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87ecqvx0a9.fsf@HIDDEN>
Date: Wed, 22 Oct 2025 19:13:12 +0300
Message-ID: <87qzuv6ij6.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Rspamd-Queue-Id: 4csDl54pGRz9scY
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

> - Support for mode hierarchy 'hs-special-modes-alist'.
>
> Previously, 'assoc' was used to get the mode and their settings to apply
> (as the deleted FIXME in the patch describes it), now it should support
> the mode and their parents, thus, just by adding (html-mode ...), it
> applies to mhtml-mode and its derivatives.

I noticed that in your patch it applies to parents instead of derivatives,
since it uses (get major-mode 'derived-mode--all-parents).

> +       (start . START)
> +       (end . END)
> +       (c-start . COMMENT-START)
> +       (fsexp-fn . FORWARD-SEXP-FUNC)
> +       (aj-beg-fn . ADJUST-BEG-FUNC)
> +       (find-beg-fn . FIND-BLOCK-BEGINNING-FUNC)
> +       (find-next-fn . FIND-NEXT-BLOCK-FUNC)
> +       (look-start-fn . LOOKING-AT-BLOCK-START-P-FUNC)
> +       (treesit-things . TREESIT-THINGS))

Most shorthands are self-explanatory, except "fsexp-fn" and "aj-beg-fn".
Better and less confusing names but still short would be for example:

          (forward-fn . FORWARD-SEXP-FUNC)
          (adjust-fn . ADJUST-BEG-FUNC)




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at 79671 <at> debbugs.gnu.org:


Received: (at 79671) by debbugs.gnu.org; 22 Oct 2025 07:02:22 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Oct 22 03:02:22 2025
Received: from localhost ([127.0.0.1]:54767 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vBSrU-0007Jl-1C
	for submit <at> debbugs.gnu.org; Wed, 22 Oct 2025 03:02:21 -0400
Received: from mout-p-101.mailbox.org ([80.241.56.151]:55112)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vBSr3-0007Io-Nk
 for 79671 <at> debbugs.gnu.org; Wed, 22 Oct 2025 03:02:11 -0400
Received: from smtp202.mailbox.org (smtp202.mailbox.org
 [IPv6:2001:67c:2050:b231:465::202])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4cs0T26clQz9t8W;
 Wed, 22 Oct 2025 09:01:42 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1761116503;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
 in-reply-to:in-reply-to:references:references;
 bh=GpJy4JUBRyyRh7alnTFd9aFJArCy8+d9BIWPNcKHb7U=;
 b=eag360KStJePiXbLrv3PL3utRaLR/EBTkE81cqPvACDT4haiV9y7m4xzTObfAB614LeMwT
 I1fWbS7O/q6GWWeX8+kz3/b154UAwZIt1ABF0KCESDaZjahiCN0+XSiU744RdUYq4suge9
 FRyH4JTk8mI6CGgchOGABYov8HNpkiHQFAEtEBWW5A6B4hnGHf0YeYxX78Q2tWHqHw6u1A
 A3jaJYqYLiP6Edt8j3PAOfAQr/U/CubJvG8N84U6mjI1XVbaJGqGgRmTeJbJF3bJuUD9KZ
 GqrJg2zRM1cNZTAW3Op6TNKf3qoWVFYh4w2BDmOtARkgXqr5JolH+Bdhyp172Q==
Authentication-Results: outgoing_mbo_mout; dkim=none;
 spf=pass (outgoing_mbo_mout: domain of juri@HIDDEN designates
 2001:67c:2050:b231:465::202 as permitted sender)
 smtp.mailfrom=juri@HIDDEN
From: Juri Linkov <juri@HIDDEN>
To: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79671: (WIP) [PATCH] hideshow: Rewrite
 'hs-special-modes-alist'
In-Reply-To: <87ecqvx0a9.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87ecqvx0a9.fsf@HIDDEN>
Date: Wed, 22 Oct 2025 09:59:45 +0300
Message-ID: <87plafs9pa.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Rspamd-Queue-Id: 4cs0T26clQz9t8W
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79671
Cc: 79671 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

> Hello, i'm writing a patch to rewrite 'hs-special-modes-alist' and
> provide the following features:

Thanks, great features.

> - Change 'hs-special-modes-alist' format.
>
> The current format of hs-special-modes-alist is cumbersome, and hard to
> read; this changes it to a new format that should make it easier to use
> (and also updates some built-in modes that set this variable).
>
> e.g.
>   before:
>   (my-mode "{" "}" "\\*" nil nil nil (things)...)
>
>   after:
>   (my-mode (start . "{") (end . "}") (c-start . "\\*") (treesit-things . (things))...)

I suppose the old format will still be supported for backward-compatibility?

> - Add an easy way to support treesit
>
> The treesit support in hideshow is partial, some modes (such as
> python-ts-mode) do not fully support folding with treesit (e.g. def).

Currently hs-minor-mode uses the hard-coded 'list' thing, which
e.g. in python-ts-mode doesn't include 'function_definition'
for compatibility with python-mode.

But to make this configurable, we could add a new thing, e.g. 'hideshow',
to be defined in 'treesit-thing-settings' instead of 'hs-special-modes-alist'.
Or maybe better to support both.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 22 Oct 2025 00:12:24 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Oct 21 20:12:24 2025
Received: from localhost ([127.0.0.1]:53768 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vBMSl-0003jy-El
	for submit <at> debbugs.gnu.org; Tue, 21 Oct 2025 20:12:24 -0400
Received: from lists.gnu.org ([2001:470:142::17]:46610)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vBMSh-0003jS-MV
 for submit <at> debbugs.gnu.org; Tue, 21 Oct 2025 20:12:21 -0400
Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <eg642616@HIDDEN>)
 id 1vBMSb-0005Lc-Al
 for bug-gnu-emacs@HIDDEN; Tue, 21 Oct 2025 20:12:14 -0400
Received: from mail-ot1-x344.google.com ([2607:f8b0:4864:20::344])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <eg642616@HIDDEN>)
 id 1vBMSY-0008PV-9S
 for bug-gnu-emacs@HIDDEN; Tue, 21 Oct 2025 20:12:12 -0400
Received: by mail-ot1-x344.google.com with SMTP id
 46e09a7af769-7c28378681cso1757412a34.1
 for <bug-gnu-emacs@HIDDEN>; Tue, 21 Oct 2025 17:12:09 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1761091928; x=1761696728; darn=gnu.org;
 h=mime-version:message-id:date:subject:to:from:from:to:cc:subject
 :date:message-id:reply-to;
 bh=PN58wvXbkzKGlPLonsHTF3GjKnmDDjZDLsI9w3htYVo=;
 b=DbGUHn8fIu1IfFpLi6GIvxo0EnWszDIY9Flj/XGRnacqGq/sFEH+zCHguGEOtqfqvd
 hPgd3OLaev9htT64BktrNrZWFd9Nci9IJOfIq5lT+1NzTIU0WLYT7l3bKZ+g7tx7PU7Y
 Jf77B5+hps1MP6SabeNoPPD2kq9k7Pb8nJUEW19rsrKj/2AafGXVjc/QhnO4ZbKFzg4b
 cszw+aWyqHYzvVzCdb1ltpcZVj82P2kxFr+MnE3vFFhzEvTRlShS4c8gAHXHq4LYL42i
 SgCPV2fm4IUK/NxdyCBxzdp4w91X8vGiXbIhofqfvSpOBxpbdNfVV1Vt5/8KwrPnTlgV
 EZxw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1761091928; x=1761696728;
 h=mime-version:message-id:date:subject:to:from:x-gm-message-state
 :from:to:cc:subject:date:message-id:reply-to;
 bh=PN58wvXbkzKGlPLonsHTF3GjKnmDDjZDLsI9w3htYVo=;
 b=s/t7m+JMwMuujv0RLt4mYb3OTlsJyGeJzitvrlaTw0ykHtcEmfVSwBYwy+IuZnnTh3
 pilIwaxtwYB6QPFdC7EvbNwvSx+Y0L+8RIADIVq3QBFOJl815y7lXBLNp+Hr18oHzUaB
 aoN/cj3RRcL3QHzPMSeaZ77caVj/6qRqoxHhl1aKVwVUEhUX18v7etGRj9eggNwYLUez
 OTvmkCIyIfl+h+Xg6vq/vy3B8l4pOpCh4L20qORfjtLf0BFWeeQ/V3Vm7aHDsqsrtuQE
 4yLgBRrEP+zEwVm4jYPlWPksqtJ/lDkF+Aw+icqgkyPMzag2/T/IpXJ/nnB4FYUp5FUz
 /SxA==
X-Gm-Message-State: AOJu0YwGGrnFyY8i9WVYbI7wKG1N5elmPDoHtsV93kY1QZQehOB/sCeC
 pfqYGSsFl4EIBUPfpSAWgFQn59NKfsATG/eMEMk7SGUgQX9mQac619/4jJth9izm
X-Gm-Gg: ASbGncvuk5OXuwBjNyFsggAMrGaAG/BAk6K6UbAUHOrhWp7ILHwsc6SQtYYTkLIZeKv
 kTnD7vtZYZIRO26gxLXLstgz4aH8wIXCwDh6MkNkNNoPcii0aQjZObcb4ujY8cv/3v9D63jKm5N
 wcpL3EWskDPsmlA264o1QGREw1f5KK4RdsQewrz2fPaDJfXOqUwvESprUI+2WoIqWFrj/TkM3WP
 hSqfHR/npiQFNPAnnLjD7CyX0AQx/tgbjb8XzmUD9yQudzHXTdCW9P00voaYlP42Nw7nb5ZDGua
 87i96kTs/h4JZytQ1eKSt2szGpzZ8ICqzHwhhu0OH4T+eXq/naSANrJU+9UX5lXTSL5LGaGJmKK
 F3n8Qj1rS0TspRLpkQ30t5ux0xoCZ/Zg/Qkp0ilAQv6y8QmU91Q4YaCeeZ/RPJS4xNHXVAzKf0G
 4YUxwj
X-Google-Smtp-Source: AGHT+IFzSODgAiKr+Jq/GobFTUiPDYLRs1MCnMMQFYHZOa71oZIb0l9ZOzp6jbfNEg/03YdPDxfEJQ==
X-Received: by 2002:a05:6808:2444:b0:441:c8a2:ba1b with SMTP id
 5614622812f47-443a2fb2232mr8123395b6e.40.1761091928221; 
 Tue, 21 Oct 2025 17:12:08 -0700 (PDT)
Received: from fedora ([189.215.161.189]) by smtp.gmail.com with ESMTPSA id
 006d021491bc7-651d3f3d553sm3192394eaf.17.2025.10.21.17.12.04
 for <bug-gnu-emacs@HIDDEN>
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Tue, 21 Oct 2025 17:12:07 -0700 (PDT)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: bug-gnu-emacs@HIDDEN
Subject: (WIP) [PATCH] hideshow: Rewrite 'hs-special-modes-alist'
Date: Tue, 21 Oct 2025 18:11:58 -0600
Message-ID: <87ecqvx0a9.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
Received-SPF: pass client-ip=2607:f8b0:4864:20::344;
 envelope-from=eg642616@HIDDEN; helo=mail-ot1-x344.google.com
X-Spam_score_int: -17
X-Spam_score: -1.8
X-Spam_bar: -
X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,
 DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,
 FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001,
 RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,
 SPF_PASS=-0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-Spam-Score: 1.2 (+)
X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org",
 has NOT identified this incoming email as spam.  The original
 message has been attached to this so you can view it or label
 similar future email.  If you have any questions, see
 the administrator of that system for details.
 Content preview:  Hello,
 i'm writing a patch to rewrite 'hs-special-modes-alist'
 and provide the following features: - Support for mode hierarchy
 'hs-special-modes-alist'.
 Previously, 'assoc' was used to get the mode and their settings to apply
 (as the deleted FIXME in the patch describes it), now it should support the
 mode and their parents, thus, just by adding (html- [...] 
 Content analysis details:   (1.2 points, 10.0 required)
 pts rule name              description
 ---- ---------------------- --------------------------------------------------
 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends
 in digit (eg642616[at]gmail.com)
 -0.0 SPF_HELO_PASS          SPF: HELO matches SPF record
 1.0 SPF_SOFTFAIL           SPF: sender does not match SPF record (softfail)
 0.0 FREEMAIL_FROM          Sender email is commonly abused enduser mail
 provider (eg642616[at]gmail.com)
 -0.0 RCVD_IN_DNSWL_NONE     RBL: Sender listed at https://www.dnswl.org/,
 no trust [2001:470:142:0:0:0:0:17 listed in] [list.dnswl.org]
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: 0.2 (/)

--=-=-=
Content-Type: text/plain

Hello, i'm writing a patch to rewrite 'hs-special-modes-alist' and
provide the following features:

- Support for mode hierarchy 'hs-special-modes-alist'.

Previously, 'assoc' was used to get the mode and their settings to apply
(as the deleted FIXME in the patch describes it), now it should support
the mode and their parents, thus, just by adding (html-mode ...), it
applies to mhtml-mode and its derivatives.

- Change 'hs-special-modes-alist' format.

The current format of hs-special-modes-alist is cumbersome, and hard to
read; this changes it to a new format that should make it easier to use
(and also updates some built-in modes that set this variable).

e.g.
  before:
  (my-mode "{" "}" "\\*" nil nil nil (things)...)

  after:
  (my-mode (start . "{") (end . "}") (c-start . "\\*") (treesit-things . (things))...)

- Add an easy way to support treesit

The treesit support in hideshow is partial, some modes (such as
python-ts-mode) do not fully support folding with treesit (e.g. def).

This patch adds a new value to hs-special-modes-alist, which should
allow to add which treesit "things" should be folded.

I haven't fully tested the treesit feature, so i would like some
suggestions regarding this change.


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow-Rewrite-hs-special-modes-alist.patch

From 68f552be39cda3e728b130e4aa64e83cff59dac4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Mon, 13 Oct 2025 18:45:21 -0600
Subject: [PATCH] hideshow: Rewrite 'hs-special-modes-alist'

Rewrite the format in 'hs-special-modes-alist' to make easier to
exclude some values, add support for mode hierarchy and better
treesit things support.

bug#

* lisp/progmodes/hideshow.el (hs-special-modes-alist): Rewrite format.
(hs-treesit-things): New buffer-local variable.
(hs-grok-mode-type): Rewrite.
* lisp/progmodes/f90.el (hs-special-modes-alist):
* lisp/progmodes/fortran.el (hs-special-modes-alist):
* lisp/progmodes/icon.el (icon-mode):
* lisp/progmodes/lua-mode.el (lua-mode):
* lisp/progmodes/python.el (python-base-mode):
* lisp/progmodes/verilog-mode.el (verilog-mode):
* lisp/progmodes/vhdl-mode.el (vhdl-hs-minor-mode): Rewrite settings.
* lisp/treesit.el (treesit-hs-block-end)
(treesit-hs-find-block-beginning, treesit-hs-find-next-block)
(treesit-hs-looking-at-block-start-p): Minor updates.
---
 lisp/progmodes/f90.el          |  4 +-
 lisp/progmodes/fortran.el      |  4 +-
 lisp/progmodes/hideshow.el     | 75 +++++++++++++++-----------
 lisp/progmodes/icon.el         |  4 +-
 lisp/progmodes/lua-mode.el     |  6 +--
 lisp/progmodes/python.el       | 16 +++---
 lisp/progmodes/verilog-mode.el |  4 +-
 lisp/progmodes/vhdl-mode.el    |  4 +-
 lisp/treesit.el                | 99 +++++++++++++++++-----------------
 9 files changed, 115 insertions(+), 101 deletions(-)

diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index 96626600d55..eecceda0d06 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -970,8 +970,8 @@ f90-start-block-re
 
 ;; hs-special-modes-alist is autoloaded.
 (add-to-list 'hs-special-modes-alist
-             `(f90-mode ,f90-start-block-re ,f90-end-block-re
-                        "!" f90-end-of-block nil))
+             `(f90-mode (start . ,f90-start-block-re) (end . ,f90-end-block-re)
+                        (c-start . "!") (fsexp-fn . f90-end-of-block)))
 
 
 ;; Imenu support.
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index d1f14fdf8fe..a28299333da 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -585,8 +585,8 @@ fortran-start-block-re
 Used in the Fortran entry in `hs-special-modes-alist'.")
 
 (add-to-list 'hs-special-modes-alist
-             `(fortran-mode ,fortran-start-block-re ,fortran-end-block-re
-                            "^[cC*!]" fortran-end-of-block nil))
+             `(fortran-mode (start . ,fortran-start-block-re) (end . ,fortran-end-block-re)
+                            (c-start . "^[cC*!]") (fsexp-fn . fortran-end-of-block)))
 
 
 (defvar fortran-mode-syntax-table
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index 6d3a5bc9fe6..0cb509d92fc 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -371,29 +371,31 @@ hs-indicator-show
 
 ;;;###autoload
 (defvar hs-special-modes-alist
-  ;; FIXME: Currently the check is made via
-  ;; (assoc major-mode hs-special-modes-alist) so it doesn't pay attention
-  ;; to the mode hierarchy.
-  '((c-mode "{" "}" "/[*/]" nil nil)
-    (c-ts-mode "{" "}" "/[*/]" nil nil)
-    (c++-mode "{" "}" "/[*/]" nil nil)
-    (c++-ts-mode "{" "}" "/[*/]" nil nil)
-    (bibtex-mode ("@\\S(*\\(\\s(\\)" 1))
-    (java-mode "{" "}" "/[*/]" nil nil)
-    (java-ts-mode "{" "}" "/[*/]" nil nil)
-    (js-mode "{" "}" "/[*/]" nil)
-    (js-ts-mode "{" "}" "/[*/]" nil)
-    (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil)
+  '((c-mode    (start . "{") (end . "}") (c-start . "/[*/]"))
+    (c++-mode  (start . "{") (end . "}") (c-start . "/[*/]"))
+    (java-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (bibtex-mode  (start . ("@\\S(*\\(\\s(\\)" 1)))
+    (js-base-mode (start . "{") (end . "}") (c-start . "/[*/]"))
+    (html-mode (start . "{\\|<[^/>]*?") (end . "}\\|</[^/>]*[^/]>")
+               (c-start . "<!--") (fsexp-fn . mhtml-forward))
     ;; Add more support here.
     )
   "Alist for initializing the hideshow variables for different modes.
-Each element has the form
-  (MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC
-   FIND-BLOCK-BEGINNING-FUNC FIND-NEXT-BLOCK-FUNC
-   LOOKING-AT-BLOCK-START-P-FUNC).
+Each element is an alist with any of the cons-cells forms:
+ (MODE &optional
+       (start . START)
+       (end . END)
+       (c-start . COMMENT-START)
+       (fsexp-fn . FORWARD-SEXP-FUNC)
+       (aj-beg-fn . ADJUST-BEG-FUNC)
+       (find-beg-fn . FIND-BLOCK-BEGINNING-FUNC)
+       (find-next-fn . FIND-NEXT-BLOCK-FUNC)
+       (look-start-fn . LOOKING-AT-BLOCK-START-P-FUNC)
+       (treesit-things . TREESIT-THINGS))
 
 If non-nil, hideshow will use these values as regexps to define blocks
-and comments, respectively for major mode MODE.
+and comments, respectively for major mode MODE or current major mode
+parents.
 
 START, END and COMMENT-START are regular expressions.  A block is
 defined as text surrounded by START and END.
@@ -420,9 +422,12 @@ hs-special-modes-alist
 See the documentation for `hs-looking-at-block-start-p-func' to
 see what is the use of LOOKING-AT-BLOCK-START-P-FUNC.
 
-If any of the elements is left nil or omitted, hideshow tries to guess
-appropriate values.  The regexps should not contain leading or trailing
-whitespace.  Case does not matter.")
+TREESIT-THINGS is a list of treesit things to determine if current block
+at point is valid, see `treesit-thing-at' to get more information about.
+
+If any of the elements in the cons-cell is left nil or omitted, hideshow
+tries to guess appropriate values.  The regexps should not contain
+leading or trailing whitespace.  Case does not matter.")
 
 (defvar hs-hide-all-non-comment-function nil
   "Function called if non-nil when doing `hs-hide-all' for non-comments.")
@@ -607,6 +612,9 @@ hs-looking-at-block-start-p-func
 (defvar-local hs-inside-comment-p-func nil
   "Function used to check if point is inside a comment.")
 
+(defvar-local hs-treesit-things nil
+  "List of treesit things to check if point is at a valid block.")
+
 (defvar hs-headline nil
   "Text of the line where a hidden block begins, set during isearch.
 You can display this in the mode line by adding the symbol `hs-headline'
@@ -990,8 +998,11 @@ hs-grok-mode-type
 function; and adjust-block-beginning function."
   (if (and (bound-and-true-p comment-start)
            (bound-and-true-p comment-end))
-      (let* ((lookup (assoc major-mode hs-special-modes-alist))
-             (start-elem (or (nth 1 lookup) "\\s(")))
+      (let* ((lookup (catch 'hs-grok-exit
+                       (dolist (mode (get major-mode 'derived-mode--all-parents))
+                         (and-let* ((ret (assoc mode hs-special-modes-alist)))
+                           (throw 'hs-grok-exit ret)))))
+             (start-elem (or (alist-get 'start lookup) "\\s(")))
         (if (listp start-elem)
             ;; handle (START-REGEXP MDATA-SELECT)
             (setq hs-block-start-regexp (car start-elem)
@@ -999,23 +1010,23 @@ hs-grok-mode-type
           ;; 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)
+        (setq hs-block-end-regexp (or (alist-get 'end lookup) "\\s)")
+              hs-c-start-regexp (or (alist-get 'c-start 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 (or (nth 5 lookup) #'identity)
-              hs-find-block-beginning-func (or (nth 6 lookup)
+              hs-forward-sexp-func (or (alist-get 'fsexp-fn lookup) #'forward-sexp)
+              hs-adjust-block-beginning (or (alist-get 'aj-beg-fn lookup) #'identity)
+              hs-find-block-beginning-func (or (alist-get 'find-beg-fn lookup)
                                                #'hs-find-block-beginning)
-              hs-find-next-block-func (or (nth 7 lookup)
+              hs-find-next-block-func (or (alist-get 'find-next-fn lookup)
                                           #'hs-find-next-block)
-              hs-looking-at-block-start-p-func
-              (or (nth 8 lookup)
-                  #'hs-looking-at-block-start-p)))
+              hs-looking-at-block-start-p-func (or (alist-get 'look-start-fn lookup)
+                                                   #'hs-looking-at-block-start-p)
+              hs-treesit-things (or (alist-get 'treesit-things lookup) 'list)))
     (setq hs-minor-mode nil)
     (error "%s Mode doesn't support Hideshow Minor Mode"
            (format-mode-line mode-name))))
diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el
index dee57956ce7..7ebd773556b 100644
--- a/lisp/progmodes/icon.el
+++ b/lisp/progmodes/icon.el
@@ -170,8 +170,8 @@ icon-mode
   ;; we start from the assertion that `hs-special-modes-alist' is autoloaded.
   (unless (assq 'icon-mode hs-special-modes-alist)
     (setq hs-special-modes-alist
-	  (cons '(icon-mode  "\\<procedure\\>" "\\<end\\>" nil
-			     icon-forward-sexp-function)
+	  (cons '(icon-mode  (start . "\\<procedure\\>") (end . "\\<end\\>")
+                             (fsexp-fn . icon-forward-sexp-function))
 		hs-special-modes-alist))))
 
 ;; This is used by indent-for-comment to decide how much to
diff --git a/lisp/progmodes/lua-mode.el b/lisp/progmodes/lua-mode.el
index 01d91637cf0..4095c97c700 100644
--- a/lisp/progmodes/lua-mode.el
+++ b/lisp/progmodes/lua-mode.el
@@ -556,9 +556,9 @@ lua-mode
   (unless (assq 'lua-mode hs-special-modes-alist)
     (add-to-list 'hs-special-modes-alist
                  `(lua-mode
-                   ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words) ; Start
-                   ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words) ; End
-                   nil lua-forward-sexp))))
+                   (start . ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words)) ; Start
+                   (end . ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words)) ; End
+                   (fsexp-fn . fsexp-fnlua-forward-sexp)))))
 
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 5a96972caa7..c6f6cda33eb 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -7344,16 +7344,16 @@ python-base-mode
     (add-to-list
      'hs-special-modes-alist
      `(,mode
-       ,python-nav-beginning-of-block-regexp
+       (start . ,python-nav-beginning-of-block-regexp)
        ;; Use the empty string as end regexp so it doesn't default to
        ;; "\\s)".  This way parens at end of defun are properly hidden.
-       ""
-       "#"
-       python-hideshow-forward-sexp-function
-       nil
-       python-nav-beginning-of-block
-       python-hideshow-find-next-block
-       python-info-looking-at-beginning-of-block)))
+       (end . "")
+       (c-start . "#")
+       (fsexp-fn . python-hideshow-forward-sexp-function)
+       (find-beg-fn . python-nav-beginning-of-block)
+       (find-next-fn . python-hideshow-find-next-block)
+       (look-start-fn . python-info-looking-at-beginning-of-block)
+       (treesit-things . (defun sexp)))))
 
   (setq-local outline-regexp (python-rx (* space) block-start))
   (setq-local outline-level
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 2f5525786e1..abc5a4f0208 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -4366,8 +4366,8 @@ verilog-mode
   (when (boundp 'hs-special-modes-alist)
     (unless (assq 'verilog-mode hs-special-modes-alist)
       (setq hs-special-modes-alist
-            (cons '(verilog-mode "\\<begin\\>" "\\<end\\>" nil
-                                 verilog-forward-sexp-function)
+            (cons '(verilog-mode (beg . "\\<begin\\>") (end . "\\<end\\>")
+                                 (fsexp-fn . verilog-forward-sexp-function))
                   hs-special-modes-alist))))
 
   (add-hook 'completion-at-point-functions
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 593a83ceffa..a81914fa921 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -13284,8 +13284,8 @@ vhdl-hs-minor-mode
     ;; initialize hideshow
     (unless (assoc 'vhdl-mode hs-special-modes-alist)
       (setq hs-special-modes-alist
-	    (cons (list 'vhdl-mode vhdl-hs-start-regexp nil "--\\( \\|$\\)"
-			'vhdl-hs-forward-sexp-func nil)
+	    (cons `(vhdl-mode (start . ,vhdl-hs-start-regexp) (c-start . "--\\( \\|$\\)")
+			      (fsexp-fn . vhdl-hs-forward-sexp-func))
 		  hs-special-modes-alist)))
     (if (featurep 'xemacs) (make-local-hook 'hs-minor-mode-hook))
     (if vhdl-hide-all-init
diff --git a/lisp/treesit.el b/lisp/treesit.el
index 69abe869cd8..c73bd5382e5 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -4169,65 +4169,68 @@ treesit-outline-level
 
 (defun treesit-hs-block-end ()
   "Tree-sitter implementation of `hs-block-end-regexp'."
-  (let* ((pred 'list)
-         (thing (treesit-thing-at
-                 (if (bobp) (point) (1- (point))) pred))
-         (end (when thing (treesit-node-end thing)))
-         (last (when thing (treesit-node-child thing -1)))
-         (beg (if last (treesit-node-start last)
-                (if (bobp) (point) (1- (point))))))
-    (when (and thing (eq (point) end))
-      (set-match-data (list beg end))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((thing (treesit-thing-at
+                   (if (bobp) (point) (1- (point))) hs-treesit-things))
+           (end (when thing (treesit-node-end thing)))
+           (last (when thing (treesit-node-child thing -1)))
+           (beg (if last (treesit-node-start last)
+                  (if (bobp) (point) (1- (point))))))
+      (when (and thing (eq (point) end))
+        (set-match-data (list beg end))
+        t))))
 
 (defun treesit-hs-find-block-beginning ()
   "Tree-sitter implementation of `hs-find-block-beginning-func'."
-  (let* ((pred 'list)
-         (thing (treesit-thing-at (point) pred))
-         (beg (when thing (treesit-node-start thing)))
-         (end (when beg (min (1+ beg) (point-max)))))
-    (when thing
-      (goto-char beg)
-      (set-match-data (list beg end))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((thing (treesit-thing-at (point) hs-treesit-things))
+           (beg (when thing (treesit-node-start thing)))
+           (end (when beg (min (1+ beg) (point-max)))))
+      (when thing
+        (goto-char beg)
+        (set-match-data (list beg end))
+        t))))
 
 (defun treesit-hs-find-next-block (_regexp maxp comments)
   "Tree-sitter implementation of `hs-find-next-block-func'."
   (when (not comments)
     (forward-comment (point-max)))
-  (let* ((comment-pred
-          (when comments
-            (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
-                'comment "\\`comment\\'")))
-         (pred (if comment-pred (append '(or list) (list comment-pred)) 'list))
-         ;; `treesit-navigate-thing' can't find a thing at bobp,
-         ;; so use `treesit-thing-at' to match at bobp.
-         (current (treesit-thing-at (point) pred))
-         (beg (or (and current (eq (point) (treesit-node-start current)) (point))
-                  (treesit-navigate-thing (point) 1 'beg pred)))
-         ;; Check if we found a list or a comment
-         (list-thing (when beg (treesit-thing-at beg 'list)))
-         (comment-thing (when beg (treesit-thing-at beg comment-pred)))
-         (comment-p (and comment-thing (eq beg (treesit-node-start comment-thing))))
-         (thing (if comment-p comment-thing list-thing))
-         (end (if thing (min (1+ (treesit-node-start thing)) (point-max)))))
-    (when (and end (<= end maxp))
-      (goto-char end)
-      (set-match-data
-       (if (and comments comment-p)
-           (list beg end nil nil beg end)
-         (list beg end beg end)))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((comment-pred
+            (when comments
+              (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
+                  'comment "\\`comment\\'")))
+           (pred (if comment-pred
+                     (append `(or ,hs-treesit-things) (list comment-pred))
+                   hs-treesit-things))
+           ;; `treesit-navigate-thing' can't find a thing at bobp,
+           ;; so use `treesit-thing-at' to match at bobp.
+           (current (treesit-thing-at (point) pred))
+           (beg (or (and current (eq (point) (treesit-node-start current)) (point))
+                    (treesit-navigate-thing (point) 1 'beg pred)))
+           ;; Check if we found a block or a comment
+           (block-thing (when beg (treesit-thing-at beg hs-treesit-things)))
+           (comment-thing (when beg (treesit-thing-at beg comment-pred)))
+           (comment-p (and comment-thing (eq beg (treesit-node-start comment-thing))))
+           (thing (if comment-p comment-thing block-thing))
+           (end (if thing (min (1+ (treesit-node-start thing)) (point-max)))))
+      (when (and end (<= end maxp))
+        (goto-char end)
+        (set-match-data
+         (if (and comments comment-p)
+             (list beg end nil nil beg end)
+           (list beg end beg end)))
+        t))))
 
 (defun treesit-hs-looking-at-block-start-p ()
   "Tree-sitter implementation of `hs-looking-at-block-start-p-func'."
-  (let* ((pred 'list)
-         (thing (treesit-thing-at (point) pred))
-         (beg (when thing (treesit-node-start thing)))
-         (end (min (1+ (point)) (point-max))))
-    (when (and thing (eq (point) beg))
-      (set-match-data (list beg end))
-      t)))
+  (when (bound-and-true-p hs-treesit-things)
+    (let* ((thing (treesit-thing-at (point) hs-treesit-things))
+           (beg (when thing (treesit-node-start thing)))
+           (end (min (1+ (point)) (point-max))))
+      (when (and thing (eq (point) beg))
+        (set-match-data (list beg end))
+        t))))
 
 (defun treesit-hs-inside-comment-p ()
   "Tree-sitter implementation of `hs-inside-comment-p-func'."
-- 
2.51.0


--=-=-=
Content-Type: text/plain


-- 
- E.G via Gnus and Org.

--=-=-=--




Acknowledgement sent to Elijah Gabe Pérez <eg642616@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to bug-gnu-emacs@HIDDEN:
bug#79671; Package emacs. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Tue, 4 Nov 2025 17:30:03 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.