GNU bug report logs - #79877
[PATCH] hideshow.el: New commands 'hs-cycle' and 'hs-toggle-all'

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 79877 <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 79877 <at> debbugs.gnu.org:


Received: (at 79877) by debbugs.gnu.org; 1 Dec 2025 17:45:04 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Dec 01 12:45:04 2025
Received: from localhost ([127.0.0.1]:51613 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vQ7xQ-0003hN-5R
	for submit <at> debbugs.gnu.org; Mon, 01 Dec 2025 12:45:04 -0500
Received: from mout-p-201.mailbox.org ([2001:67c:2050:0:465::201]:41906)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>)
 id 1vQ7xN-0003g1-2Q; Mon, 01 Dec 2025 12:45:01 -0500
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 4dKrrj2xKCz9sx4;
 Mon,  1 Dec 2025 18:44:53 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1764611093;
 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=T2s3WgooEwYNQSo8BXTcjco9sbC+iF2rvtNB3Ml3WS8=;
 b=k9Nip/EnKDgoejFgd/1Ztkl7R63MRDYhX1gZMUzT6da4KMZ3T/mjTceCiLME1dHCn7F7gL
 LuiSDlSaKQMFPGoV8uqOLSvadpT7Jd9vR4SixERkflECJwqYgmjpu7c+q/NESNl7i+C9Bb
 oCqLR4NnmqtaVW99uoTnFCjVfUS+rCDuvZXpaaKPP6kI+JDIrS+714HnvtgIsfnupmBRmm
 1iqD5q99EuQp5l9BBiF3wOVXw6oWRin9+5nNTy8/1rLxXd/ZlAr/7GFDg8YNSk8bjCLD6z
 w3FUeXRVXY5z6350xv/rZ6vgfG6aknIKcOX7Tcpx3iyQ6ZKclQECwwdJl02Ziw==
From: Juri Linkov <juri@HIDDEN>
To: Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
In-Reply-To: <87ms448gam.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
 <87bjko17fi.fsf@HIDDEN> <86ikewasy0.fsf@HIDDEN>
 <87fr9zw7oz.fsf@HIDDEN> <86ecpiaayn.fsf@HIDDEN>
 <87ecpiy6ap.fsf@HIDDEN> <87v7iu9fn1.fsf@HIDDEN>
 <87qztg92c0.fsf@HIDDEN> <87ms448gam.fsf@HIDDEN>
Date: Mon, 01 Dec 2025 19:44:00 +0200
Message-ID: <87ldjm6qsf.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79877
Cc: 79877 <at> debbugs.gnu.org, Eli Zaretskii <eliz@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 (-)

close 79877 31.0.50
thanks

>> While trying, I noticed that 'C-c @ TAB' unexpectedly hides the current line,
>> because it hides the parent that can be far away above the current line.
>> Shouldn't it hide the block that starts on the current line?
>
> Something similar to what `hs-hide-block` does?.
>
> Yeah, I was wondering if its code should be only part of that command or
> be like `hs-get-first-block` to general purposes.  I've fixed it.

Thanks, it works great.  Now pushed and closed.




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

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


Received: (at 79877) by debbugs.gnu.org; 30 Nov 2025 01:23:28 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 29 20:23:28 2025
Received: from localhost ([127.0.0.1]:33913 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vPW9v-0000t6-8L
	for submit <at> debbugs.gnu.org; Sat, 29 Nov 2025 20:23:28 -0500
Received: from mail-ot1-x341.google.com ([2607:f8b0:4864:20::341]:50251)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vPW9r-0000sQ-7M
 for 79877 <at> debbugs.gnu.org; Sat, 29 Nov 2025 20:23:25 -0500
Received: by mail-ot1-x341.google.com with SMTP id
 46e09a7af769-7c75fc222c3so1052003a34.0
 for <79877 <at> debbugs.gnu.org>; Sat, 29 Nov 2025 17:23:23 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1764465797; x=1765070597; 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=Ze5Zbld3q6p3Yp5vPyN8W1j5psN8fNBVkgjjajdLKhQ=;
 b=i0ziR9EI6Zbtm2bqAtJLppbk7ZS1eV2jK030/vvw25xu/B/B69rP6uMKXr6J/p6P8l
 uNp3Qos2i03ckYi0a3a6pJu9fk5tKvUItuelJT4xJV6008TBLwXC9eMEfxlGgEcOpUKq
 m/NGL8ZrxPZhi22FGmG37RFYMHqtZ0pkgBpOdSEwS1JTmu5frP9ey3A6vMJOyYrEAURJ
 wuwSDWNDDqEUZlojGW0qphViFkLHDl5O0TF80OSUZOu3ElsB33OxLY0J9CCvzuvrKJPc
 AqTUaksQn8BidfCsHjD87AoNQmM24ElcsKE6Av97nv0OwcJ/pGJ4pB3o0zGtpfFd+/r7
 OwVA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1764465797; x=1765070597;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject
 :date:message-id:reply-to;
 bh=Ze5Zbld3q6p3Yp5vPyN8W1j5psN8fNBVkgjjajdLKhQ=;
 b=K/SUAer6nGlFH1g4A18B+SpxBvgUU0f/ID1uqTevs39U0uX/zAV4b7NQuqsOzBON22
 yIIeEY5qWNgQIk/I76j8LOfml/bdnhyozTZgR5Va1xQF82gwynUgNBPwEHsjr0ipY4+e
 CC9g48aDlVeN9OAQ4AfnoKbNTtAwYT4v/z/AQD1/crUIWXH6eZxHRzJ2EAPT4JOSdDWE
 VtFF/wRrYGhiXohWnBorJvcMprP9hyKBdtRU6k5lRZJq4NVjco5XaWIkoNIRzJ1+rK/5
 W5fBOW1WIj1dpoALnqfV2r75ktX5+R3MrwglNb1hqW7U1lsPN0B8IQnD5KkrLsEvCod1
 MsDA==
X-Gm-Message-State: AOJu0YzqIisQjh3WdVaiArCKDdpltcAgsy8+A0TU30C8B0nzAQVH0wBT
 zsqOwfaE7Buo0Bp72b15sT7uEGkXNNScE5KAcjraOMMb6X0bZr+RTRst
X-Gm-Gg: ASbGncvFTsSOsYmGNuwnpYeDXMkM+sD04JEGBVmFXojpKslFlhZdBpR86ywjzAQ2djX
 UGjnGrdssd6u4FeyPF+OHU546X83ZCoiZ6yn1rNVsaVLNyILgMJj+wSsq/E0GeT12KCMClbD8gl
 Q7CGair8nGuRWYWkZB1sSwtXZ8e0Xq7/U4bvX+wWqPWxEiQRZFVXqJq1a3cWSOORzaXKixbzq0I
 nbEzCv+dUtYH5rEuWVBvMNgfknBhO9cjpAurd0/vWJVwLOCL6kl6P3AgoBdVMbiB3bg4O2fgjqa
 nF6+Fo5rFEF7qgIwBXqY9zySuW1tqTq8krNiQiJGsNU2ixiI1aQ68rTt83JS5+U2a1PsOsWhCy+
 pWskpENSMqo2jrNPUOGmNGL1tNNBrflPhm+AByMv20jV2gTogqszCY2mD/Wkuy7tjwybAQuAzL5
 Rj0a/K
X-Google-Smtp-Source: AGHT+IH04RwSms5vTJDDfOlp4oGpfrVbBjp2TVwIbJBBAGgTo1x6DrJUZ7/IBjHFd+NCyTxR4o844w==
X-Received: by 2002:a05:6830:6f28:b0:7bc:31fe:57a9 with SMTP id
 46e09a7af769-7c799094aa2mr13568838a34.31.1764465797111; 
 Sat, 29 Nov 2025 17:23:17 -0800 (PST)
Received: from fedora ([189.215.160.233]) by smtp.gmail.com with ESMTPSA id
 46e09a7af769-7c91002571asm3252023a34.26.2025.11.29.17.23.15
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Sat, 29 Nov 2025 17:23:16 -0800 (PST)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Juri Linkov <juri@HIDDEN>
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
In-Reply-To: <87qztg92c0.fsf@HIDDEN>
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
 <87bjko17fi.fsf@HIDDEN> <86ikewasy0.fsf@HIDDEN>
 <87fr9zw7oz.fsf@HIDDEN> <86ecpiaayn.fsf@HIDDEN>
 <87ecpiy6ap.fsf@HIDDEN> <87v7iu9fn1.fsf@HIDDEN>
 <87qztg92c0.fsf@HIDDEN>
Date: Sat, 29 Nov 2025 19:23:13 -0600
Message-ID: <87ms448gam.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: 79877
Cc: 79877 <at> debbugs.gnu.org, Eli Zaretskii <eliz@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

Juri Linkov <juri@HIDDEN> writes:

>>> C-c @ TAB
>>> C-c @ S-TAB
>>
>> Thanks, i've updated the patch.
>
> While trying, I noticed that 'C-c @ TAB' unexpectedly hides the current line,
> because it hides the parent that can be far away above the current line.
> Shouldn't it hide the block that starts on the current line?

Something similar to what `hs-hide-block` does?.

Yeah, I was wondering if its code should be only part of that command or
be like `hs-get-first-block` to general purposes.  I've fixed it.


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow.el-New-commands-hs-cycle-and-hs-toggle-all-.patch

From 63e1013715f25710828de2b92158194d544325d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Thu, 18 Sep 2025 19:24:53 -0600
Subject: [PATCH] hideshow.el: New commands 'hs-cycle' and 'hs-toggle-all'. 
 (Bug#79877)

* etc/NEWS: Announce features.
* doc/emacs/programs.texi (Hideshow): Document it.
* lisp/progmodes/hideshow.el (hs-prefix-map): Bind the new
commands.
(hs-hide-level-recursive): Simplify.
(hs--toggle-all-state): New variable.
(hs-toggle-all, hs-cycle): New commands.
(hs-get-near-block): New function.
(hs-hide-block): Simplify.

Co-authored-by: Karthik Chikmagalur <karthikchikmagalur@HIDDEN>
---
 doc/emacs/programs.texi    |   7 ++
 etc/NEWS                   |  10 +++
 lisp/progmodes/hideshow.el | 163 ++++++++++++++++++++++++++++---------
 3 files changed, 140 insertions(+), 40 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 0adb90b36cb..6acd04d0bae 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1699,6 +1699,7 @@ Hideshow
 @findex hs-show-region
 @findex hs-hide-level
 @findex hs-toggle-hiding
+@findex hs-cycle
 @kindex C-c @@ C-h
 @kindex C-c @@ C-s
 @kindex C-c @@ C-c
@@ -1706,6 +1707,8 @@ Hideshow
 @kindex C-c @@ C-M-s
 @kindex C-c @@ C-r
 @kindex C-c @@ C-l
+@kindex C-c @@ TAB
+@kindex C-c @@ <backtab>
 @kindex S-mouse-2
 @table @kbd
 @item C-c @@ C-h
@@ -1726,6 +1729,10 @@ Hideshow
 @item C-u @var{n} C-c @@ C-l
 Hide all blocks @var{n} levels below this block
 (@code{hs-hide-level}).
+@item C-c @@ TAB
+Cycle the visibility state of the current block (@code{hs-cycle}).
+@item C-c @@ <backtab>
+Either hide or show all the blocks in the current buffer. (@code{hs-toggle-all}).
 @end table
 
 @vindex hs-hide-comments-when-hiding-all
diff --git a/etc/NEWS b/etc/NEWS
index 7d132356484..108ad599ef8 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1082,6 +1082,16 @@ convention (regexp arg second) and Emacs convention (regexp arg first).
 
 ** Hideshow
 
++++
+*** New command 'hs-cycle'.
+This command cycles the visibility state of the current block between
+hide the parent block, hide the nested blocks only and show all the
+blocks.
+
++++
+*** New command 'hs-toggle-all'.
+This command hide or show all the blocks in the current buffer.
+
 +++
 *** New user option 'hs-display-lines-hidden'.
 If this option is non-nil, Hideshow displays the number of hidden lines
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index ac0c68a0410..e916d2091c5 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -39,6 +39,8 @@
 ;;   `hs-toggle-hiding'                   C-c @ C-c
 ;;   `hs-toggle-hiding'                   S-<mouse-2>
 ;;   `hs-hide-initial-comment-block'
+;;   `hs-cycle'                           C-c @ TAB
+;;   `hs-toggle-all'                      C-c @ <backtab>
 ;;
 ;; All these commands are defined in `hs-prefix-map',
 ;; `hs-minor-mode-map' and `hs-indicators-map'.
@@ -504,16 +506,18 @@ hs-prefix-map
   :doc "Keymap for hideshow commands."
   :prefix t
   ;; These bindings roughly imitate those used by Outline mode.
-  "C-h"   #'hs-hide-block
-  "C-s"   #'hs-show-block
-  "C-M-h" #'hs-hide-all
-  "C-M-s" #'hs-show-all
-  "C-l"   #'hs-hide-level
-  "C-c"   #'hs-toggle-hiding
-  "C-a"   #'hs-show-all
-  "C-t"   #'hs-hide-all
-  "C-d"   #'hs-hide-block
-  "C-e"   #'hs-toggle-hiding)
+  "C-h"       #'hs-hide-block
+  "C-d"       #'hs-hide-block
+  "C-s"       #'hs-show-block
+  "C-M-h"     #'hs-hide-all
+  "C-t"       #'hs-hide-all
+  "C-M-s"     #'hs-show-all
+  "C-a"       #'hs-show-all
+  "C-l"       #'hs-hide-level
+  "C-c"       #'hs-toggle-hiding
+  "C-e"       #'hs-toggle-hiding
+  "TAB"       #'hs-cycle
+  "<backtab>" #'hs-toggle-all)
 
 (defvar-keymap hs-minor-mode-map
   :doc "Keymap for hideshow minor mode."
@@ -589,6 +593,8 @@ hs-headline
 
 Note that `mode-line-format' is buffer-local.")
 
+(defvar-local hs--toggle-all-state)
+
 ;;---------------------------------------------------------------------------
 ;; API variables
 
@@ -1057,6 +1063,34 @@ hs-get-first-block
                     t))))
     exit))
 
+(defun hs-get-near-block (&optional include-comment)
+  "Reposition point to a near block around point.
+It search for a valid block before and after point and return t if one
+is found.
+
+If INCLUDE-COMMENT is non-nil, it also searches for a comment block,
+returning `comment' if one is found."
+  (let ((c-reg (when include-comment (funcall hs-inside-comment-predicate)))
+        pos)
+    (cond
+     ((and c-reg (car c-reg) (hs-hideable-region-p
+                              (car c-reg) (cadr c-reg)))
+      (goto-char (car c-reg))
+      'comment)
+
+     ((and (eq hs-hide-block-behavior 'after-bol)
+           (save-excursion
+             (goto-char (line-beginning-position))
+             (setq pos (hs-get-first-block))))
+      (goto-char pos)
+      t)
+
+     ((and (or (funcall hs-looking-at-block-start-predicate)
+               (and (goto-char (line-beginning-position))
+                    (funcall hs-find-block-beginning-function)))
+           (hs-hideable-region-p))
+      t))))
+
 (defun hs-inside-comment-p ()
   (declare (obsolete "Call `hs-inside-comment-predicate' instead." "31.1"))
   (funcall hs-inside-comment-predicate))
@@ -1184,26 +1218,35 @@ hs-find-next-block
   (and (< (point) maxp)
        (re-search-forward regexp maxp t)))
 
-(defun hs-hide-level-recursive (arg minp maxp)
-  "Recursively hide blocks ARG levels below point in region (MINP MAXP)."
+(defun hs-hide-level-recursive (arg &optional beg end)
+  "Recursively hide blocks between BEG and END that are ARG levels below point.
+If BEG and END are not specified, it will search for a near block and
+use its position instead.
+
+If point is inside a block, it will use the current block positions
+instead of BEG and END."
+  ;; If we are near of a block, set BEG and END according to that
+  ;; block positions.
   (when (funcall hs-find-block-beginning-function)
-    (setq minp (1+ (point)))
-    (funcall hs-forward-sexp-function 1)
-    (setq maxp (1- (point))))
-  (unless hs-allow-nesting
-    (hs-discard-overlays minp maxp))
-  (goto-char minp)
-  (while (funcall hs-find-next-block-function hs-block-start-regexp maxp nil)
-    (when (save-match-data
-	    (not (nth 8 (syntax-ppss)))) ; not inside comments or strings
-      (if (> arg 1)
-	  (hs-hide-level-recursive (1- arg) minp maxp)
-        ;; `hs-hide-block-at-point' already moves the cursor, but if it
-        ;; fails, return to the previous position where we were.
-	(unless (and (goto-char (match-beginning hs-block-start-mdata-select))
-	             (hs-hide-block-at-point t))
-            (goto-char (match-end hs-block-start-mdata-select))))))
-  (goto-char maxp))
+    (let ((block (hs-block-positions)))
+      (setq beg (point) end (cadr block))))
+
+  ;; Show all blocks in that region
+  (unless hs-allow-nesting (hs-discard-overlays beg end))
+
+  ;; Skip initial block
+  (goto-char (1+ beg))
+
+  (while (funcall hs-find-next-block-function hs-block-start-regexp end nil)
+    (if (> arg 1)
+	(hs-hide-level-recursive (1- arg))
+      ;; `hs-hide-block-at-point' already moves the cursor, but if it
+      ;; fails, return to the previous position where we were.
+      (unless (and (goto-char (match-beginning hs-block-start-mdata-select))
+	           (hs-hide-block-at-point t))
+        (goto-char (match-end hs-block-start-mdata-select)))))
+
+  (goto-char end))
 
 (defmacro hs-life-goes-on (&rest body)
   "Evaluate BODY forms if variable `hs-minor-mode' is non-nil.
@@ -1331,17 +1374,7 @@ hs-hide-block
 
       (c-reg (hs-hide-block-at-point end c-reg))
 
-      ((save-excursion
-         (and-let* ((_ (eq hs-hide-block-behavior 'after-bol))
-                    (_ (goto-char (line-beginning-position)))
-                    (pos (hs-get-first-block))
-                    (_ (goto-char pos))
-                    (_ (hs-hide-block-at-point end))))))
-
-      ((or (funcall hs-looking-at-block-start-predicate)
-           (and (goto-char (line-beginning-position))
-                (funcall hs-find-block-beginning-function)))
-       (hs-hide-block-at-point end)))
+      ((hs-get-near-block) (hs-hide-block-at-point)))
 
      (run-hooks 'hs-hide-hook))))
 
@@ -1442,6 +1475,56 @@ hs-hide-initial-comment-block
          (when (hs-hideable-region-p beg end)
            (hs-hide-comment-region beg end)))))))
 
+(defun hs-cycle (&optional level)
+  "Cycle the visibility state of the current block.
+This cycles the visibility of the current block between hide the parent
+block, hide the nested blocks only, and show the parent and nested
+blocks.
+
+If LEVEL is specified (interactively, the prefix numeric argument), hide
+only blocks which are that many levels below the level of point."
+  (interactive "p")
+  (hs-life-goes-on
+   (when-let* ((ret (hs-get-near-block :include-comments)))
+     (cond ((eq ret 'comment)
+            (hs-toggle-hiding)
+            (message "Toggle visibility"))
+           ((> level 1)
+            (hs-hide-level-recursive level)
+            (message "Hide %d level" level))
+           (t
+            (let* (hs-allow-nesting
+                   (block (hs-block-positions))
+                   (ov (seq-find
+                        (lambda (o)
+                          (and (eq (overlay-get o 'invisible) 'hs)))
+                        (overlays-in (car block) (cadr block)))))
+              (cond
+               ;; Hide all if there are no hidden blocks
+               ((not ov)
+                (hs-hide-block)
+                (message "Hide block and nested blocks"))
+               ;; Hide the children blocks if the parent block is hidden
+               ((and (= (overlay-start ov) (car block))
+                     (= (overlay-end ov) (cadr block)))
+                (hs-hide-level-recursive 1)
+                (message "Hide first nested blocks"))
+               ;; Otherwise show all in the parent block, we cannot use
+               ;; `hs-show-block' here because we already know the
+               ;; positions.
+               (ov (hs-discard-overlays (car block) (cadr block))
+                   (message "Show block and nested blocks")
+                   (run-hooks 'hs-show-hook)))))))))
+
+(defun hs-toggle-all ()
+  "Hide or show all the blocks in the current buffer."
+  (interactive)
+  (if hs--toggle-all-state
+      (let (hs-allow-nesting)
+        (hs-discard-overlays (point-min) (point-max)))
+    (hs-hide-all))
+  (setq-local hs--toggle-all-state (not hs--toggle-all-state)))
+
 ;;;###autoload
 (define-minor-mode hs-minor-mode
   "Minor mode to selectively hide/show code and comment blocks.
-- 
2.51.1


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


-- 
- E.G via Gnus and Org.

--=-=-=--




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

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


Received: (at 79877) by debbugs.gnu.org; 29 Nov 2025 17:27:58 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Nov 29 12:27:58 2025
Received: from localhost ([127.0.0.1]:59050 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vPOjm-0003Be-6W
	for submit <at> debbugs.gnu.org; Sat, 29 Nov 2025 12:27:58 -0500
Received: from mout-p-201.mailbox.org ([80.241.56.171]:37560)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vPOji-0003BI-Ht
 for 79877 <at> debbugs.gnu.org; Sat, 29 Nov 2025 12:27:56 -0500
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-201.mailbox.org (Postfix) with ESMTPS id 4dJcYt6mn5z9tKQ;
 Sat, 29 Nov 2025 18:27:46 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1764437267;
 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=PCIy+7LVwVri1OBzkggmS2NIfKxwI4wiAb3fCE72j4Y=;
 b=R/VMv3JMYZupPsvtS+S7aOPQFplClZV8gMFtU7tsXP6L79JGTBKzU80jvknnfTOQTT6Kyg
 TyuxEsd76gEQDlqEry/mBJutzF27OVQMs6Xli3ts9tfIkGB+LLFlxR3h8cYHj+MX/bQ/2D
 OAToqpISm4gg5y80StgvERj1Sqx6iM+/5VrNH9KMAjGFAt0pvU0UDnrpYReV6lvTNCAs47
 A7YrJXqnmJ8oCL0yyFMTHBZ94hv064kzOukp7AzgUIJOXXt4Ir0kW1GqZYvJw+8eRJ7UnO
 fAJOoVVcHraUeGs2MJk3x8fHMBxJGZAZpMkFQ4j4W5vdDTCoPqG6HdotHnfCkw==
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#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
In-Reply-To: <87v7iu9fn1.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
 <87bjko17fi.fsf@HIDDEN> <86ikewasy0.fsf@HIDDEN>
 <87fr9zw7oz.fsf@HIDDEN> <86ecpiaayn.fsf@HIDDEN>
 <87ecpiy6ap.fsf@HIDDEN> <87v7iu9fn1.fsf@HIDDEN>
Date: Sat, 29 Nov 2025 19:27:11 +0200
Message-ID: <87qztg92c0.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Rspamd-Queue-Id: 4dJcYt6mn5z9tKQ
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79877
Cc: 79877 <at> debbugs.gnu.org, Eli Zaretskii <eliz@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 (-)

>> C-c @ TAB
>> C-c @ S-TAB
>
> Thanks, i've updated the patch.

While trying, I noticed that 'C-c @ TAB' unexpectedly hides the current line,
because it hides the parent that can be far away above the current line.
Shouldn't it hide the block that starts on the current line?




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

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


Received: (at 79877) by debbugs.gnu.org; 28 Nov 2025 18:27:47 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Nov 28 13:27:47 2025
Received: from localhost ([127.0.0.1]:48698 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vP3C7-0004hY-0h
	for submit <at> debbugs.gnu.org; Fri, 28 Nov 2025 13:27:47 -0500
Received: from mail-oa1-x41.google.com ([2001:4860:4864:20::41]:54301)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vP3C2-0004hA-Ee
 for 79877 <at> debbugs.gnu.org; Fri, 28 Nov 2025 13:27:45 -0500
Received: by mail-oa1-x41.google.com with SMTP id
 586e51a60fabf-3ece54945d9so543103fac.0
 for <79877 <at> debbugs.gnu.org>; Fri, 28 Nov 2025 10:27:42 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1764354456; x=1764959256; 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=P8c8HZYNU8qFQivJCiWKC4oWkOjf+HYCa9ofPYNlTg4=;
 b=GuuXnOTpb8b4gxW5qzQA+glUlrUSCLaZK2xfcOOXML5UWZHRETjBqHCbe79kkFuYzr
 PVQIlqHKwgEizxbMqZlN80aTJD7V+dt8LUWu2eNiThHl8jznyDTJCLePUxxeSr90NEMg
 Yjch+TIKz+1dDaVXLbzhXaxZbQBJK4+8jS6qktT9EuHHTOvMeAuk7Pw9ACXA7COpusYZ
 9+nvbZ0W742k66e+bqbyo1SM5b7hfW2XVVexMw1ruhOVwVJNG4X1+2yeaJQvJglNKB0F
 B8KIgRxYEFU5fdngyBEO4b+sXcdc15oqZKXdjkwy38F74dsZYfT2LNSYDCOhuSj0fE4T
 DNdA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1764354456; x=1764959256;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject
 :date:message-id:reply-to;
 bh=P8c8HZYNU8qFQivJCiWKC4oWkOjf+HYCa9ofPYNlTg4=;
 b=CQx9EFZGRWfefBX0DBLo8I1wuuwENyqoUxgImuThU7bHCpu1PODm206ccyRHqY+VH+
 y4zjMjs1SLUWGo4+PPnu/Lu5m2H1aRsuKlEQrood0ZC9AEvaIGfz7V84bglg5btLGJrG
 QyYK+Tk6xdxoxzpT7lwEXFhoaENKDaqY57EodidpsRQbfHP3p5GmnQYhu1Vc47IsIO2K
 tZ2ZPa/CCfHxbb+C4d1BqRNp6nTF88NmvriYyk24vWJnSiot3JOxe5AkEOdvJqyBGpIc
 rHuFvuv845LCaA65hpI8eurKTr9A8XtVE7YUDOG2hhliUCYxMJ6hm7uADp/66Hb1lfUV
 Nt2A==
X-Forwarded-Encrypted: i=1;
 AJvYcCXUXhqLjOlIWc5UD1cZGscM2TbPkpUbwXI/hvhYSVYns6bJs5lBfJv3StA1lHLmrrEtklgJ4g==@debbugs.gnu.org
X-Gm-Message-State: AOJu0YzGZMmk67MUBdXFz1ZPtQJVQ0xk/cZhzgDx8g+mdTF16b3s2h9z
 B0C4DNWoKHabp4qhKKMLztiRznji/xWkEAbYF40ZE5OJnGZfI1isj5Y6jJCONu0A
X-Gm-Gg: ASbGncuLDngyVtDweaxU0lfrSu9nDekMoVG326DUtmL9bDTIrcEXOlpwk2i8LdEGe2E
 qcRLMfiEcRdDEhIYz8mtBPwfyNoM4odmJx/9VfkZeFKT8Rxtp2clnoSmrhiryd8zoq7bjdw4yU8
 fupq9C9C7Dk0ZA9S2IU9xVInL8s+OqwxTnjNzXbVsGny9XGxJPmXD/SBGXbgdnfDscqcib+umXe
 dREP+nVTwxuSOKUJMZH6YrbFnVEOlrdu4h3v/mOFetUpjDTiD592ZPbuckbYfA02oODWfSRG5Kg
 DmMqo1FzO6AzopCkObBZEGsZHDeHb+dFEiKi3G7eJ13NDzgA5aBirZucGIwaG0DD8vicX9y4gUj
 dhTKk5pLFYDrxPTMy6+BjsM/tcZ4mXPaSM4c9Q90wQLYKKpK7SIoOVeO0hCvCEdXMzVqIf8s9Tz
 l+CgG5
X-Google-Smtp-Source: AGHT+IHByIQxjgNO2oQTp4QWY/ZS8jPJxS5IT5p3PX6xIZV0IKgheOMZWLHv9sA4aPsCsz3+bhqN+g==
X-Received: by 2002:a05:6808:1891:b0:44f:e61d:189f with SMTP id
 5614622812f47-45115865582mr11507696b6e.13.1764354455626; 
 Fri, 28 Nov 2025 10:27:35 -0800 (PST)
Received: from fedora ([189.215.160.233]) by smtp.gmail.com with ESMTPSA id
 006d021491bc7-65933ef2772sm1094664eaf.17.2025.11.28.10.27.32
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Fri, 28 Nov 2025 10:27:34 -0800 (PST)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Juri Linkov <juri@HIDDEN>
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
In-Reply-To: <87ecpiy6ap.fsf@HIDDEN>
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
 <87bjko17fi.fsf@HIDDEN> <86ikewasy0.fsf@HIDDEN>
 <87fr9zw7oz.fsf@HIDDEN> <86ecpiaayn.fsf@HIDDEN>
 <87ecpiy6ap.fsf@HIDDEN>
Date: Fri, 28 Nov 2025 12:27:30 -0600
Message-ID: <87v7iu9fn1.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: 79877
Cc: 79877 <at> debbugs.gnu.org, Eli Zaretskii <eliz@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:

> That's fine, but the doc string should mention that these arguments
> are not used, even if specified, if point is inside a block.

I see, thank you.

------------------------------------------------------------------------

Juri Linkov <juri@HIDDEN> writes:

>>> >> +  "C-TAB"   #'hs-cycle
>>> >> +  "C-S-TAB" #'hs-toggle-all)
>>> >
>>> > These bindings are problematic, because they won't work on text-only
>>> > terminals, at least some of them.  Can we come up with either
>>> > alternative or additional bindings that could be used on TTYs?
>>> 
>>> I prefer adding additional bindings, but I don't know which ones to use.
>>
>> Juri (or anyone else), any suggestions?
>
> Maybe
>
> C-c @ TAB
> C-c @ S-TAB

Thanks, i've updated the patch.

I had to use <backtab> instead of S-TAB because the latter is not
recognized.


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow.el-New-commands-hs-cycle-and-hs-toggle-all-.patch

From 3afba6acdfec15d415bc9a3307dcaea74dc1e0de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Thu, 18 Sep 2025 19:24:53 -0600
Subject: [PATCH] hideshow.el: New commands 'hs-cycle' and 'hs-toggle-all'. 
 (Bug#79877)

* etc/NEWS: Announce features.
* doc/emacs/programs.texi (Hideshow): Document it.
* lisp/progmodes/hideshow.el (hs-prefix-map): Bind the new
commands.
(hs-hide-level-recursive): Simplify.
(hs--toggle-all-state): New variable.
(hs-toggle-all, hs-cycle): New commands.

Co-authored-by: Karthik Chikmagalur <karthikchikmagalur@HIDDEN>
---
 doc/emacs/programs.texi    |   7 +++
 etc/NEWS                   |  10 +++
 lisp/progmodes/hideshow.el | 124 ++++++++++++++++++++++++++++---------
 3 files changed, 112 insertions(+), 29 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 0adb90b36cb..6acd04d0bae 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1699,6 +1699,7 @@ Hideshow
 @findex hs-show-region
 @findex hs-hide-level
 @findex hs-toggle-hiding
+@findex hs-cycle
 @kindex C-c @@ C-h
 @kindex C-c @@ C-s
 @kindex C-c @@ C-c
@@ -1706,6 +1707,8 @@ Hideshow
 @kindex C-c @@ C-M-s
 @kindex C-c @@ C-r
 @kindex C-c @@ C-l
+@kindex C-c @@ TAB
+@kindex C-c @@ <backtab>
 @kindex S-mouse-2
 @table @kbd
 @item C-c @@ C-h
@@ -1726,6 +1729,10 @@ Hideshow
 @item C-u @var{n} C-c @@ C-l
 Hide all blocks @var{n} levels below this block
 (@code{hs-hide-level}).
+@item C-c @@ TAB
+Cycle the visibility state of the current block (@code{hs-cycle}).
+@item C-c @@ <backtab>
+Either hide or show all the blocks in the current buffer. (@code{hs-toggle-all}).
 @end table
 
 @vindex hs-hide-comments-when-hiding-all
diff --git a/etc/NEWS b/etc/NEWS
index 7d132356484..108ad599ef8 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1082,6 +1082,16 @@ convention (regexp arg second) and Emacs convention (regexp arg first).
 
 ** Hideshow
 
++++
+*** New command 'hs-cycle'.
+This command cycles the visibility state of the current block between
+hide the parent block, hide the nested blocks only and show all the
+blocks.
+
++++
+*** New command 'hs-toggle-all'.
+This command hide or show all the blocks in the current buffer.
+
 +++
 *** New user option 'hs-display-lines-hidden'.
 If this option is non-nil, Hideshow displays the number of hidden lines
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index ac0c68a0410..8b29d1c5d4d 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -39,6 +39,8 @@
 ;;   `hs-toggle-hiding'                   C-c @ C-c
 ;;   `hs-toggle-hiding'                   S-<mouse-2>
 ;;   `hs-hide-initial-comment-block'
+;;   `hs-cycle'                           C-c @ TAB
+;;   `hs-toggle-all'                      C-c @ <backtab>
 ;;
 ;; All these commands are defined in `hs-prefix-map',
 ;; `hs-minor-mode-map' and `hs-indicators-map'.
@@ -504,16 +506,18 @@ hs-prefix-map
   :doc "Keymap for hideshow commands."
   :prefix t
   ;; These bindings roughly imitate those used by Outline mode.
-  "C-h"   #'hs-hide-block
-  "C-s"   #'hs-show-block
-  "C-M-h" #'hs-hide-all
-  "C-M-s" #'hs-show-all
-  "C-l"   #'hs-hide-level
-  "C-c"   #'hs-toggle-hiding
-  "C-a"   #'hs-show-all
-  "C-t"   #'hs-hide-all
-  "C-d"   #'hs-hide-block
-  "C-e"   #'hs-toggle-hiding)
+  "C-h"       #'hs-hide-block
+  "C-d"       #'hs-hide-block
+  "C-s"       #'hs-show-block
+  "C-M-h"     #'hs-hide-all
+  "C-t"       #'hs-hide-all
+  "C-M-s"     #'hs-show-all
+  "C-a"       #'hs-show-all
+  "C-l"       #'hs-hide-level
+  "C-c"       #'hs-toggle-hiding
+  "C-e"       #'hs-toggle-hiding
+  "TAB"       #'hs-cycle
+  "<backtab>" #'hs-toggle-all)
 
 (defvar-keymap hs-minor-mode-map
   :doc "Keymap for hideshow minor mode."
@@ -589,6 +593,8 @@ hs-headline
 
 Note that `mode-line-format' is buffer-local.")
 
+(defvar-local hs--toggle-all-state)
+
 ;;---------------------------------------------------------------------------
 ;; API variables
 
@@ -1184,26 +1190,35 @@ hs-find-next-block
   (and (< (point) maxp)
        (re-search-forward regexp maxp t)))
 
-(defun hs-hide-level-recursive (arg minp maxp)
-  "Recursively hide blocks ARG levels below point in region (MINP MAXP)."
+(defun hs-hide-level-recursive (arg &optional beg end)
+  "Recursively hide blocks between BEG and END that are ARG levels below point.
+If BEG and END are not specified, it will search for a near block and
+use its position instead.
+
+If point is inside a block, it will use the current block positions
+instead of BEG and END."
+  ;; If we are near of a block, set BEG and END according to that
+  ;; block positions.
   (when (funcall hs-find-block-beginning-function)
-    (setq minp (1+ (point)))
-    (funcall hs-forward-sexp-function 1)
-    (setq maxp (1- (point))))
-  (unless hs-allow-nesting
-    (hs-discard-overlays minp maxp))
-  (goto-char minp)
-  (while (funcall hs-find-next-block-function hs-block-start-regexp maxp nil)
-    (when (save-match-data
-	    (not (nth 8 (syntax-ppss)))) ; not inside comments or strings
-      (if (> arg 1)
-	  (hs-hide-level-recursive (1- arg) minp maxp)
-        ;; `hs-hide-block-at-point' already moves the cursor, but if it
-        ;; fails, return to the previous position where we were.
-	(unless (and (goto-char (match-beginning hs-block-start-mdata-select))
-	             (hs-hide-block-at-point t))
-            (goto-char (match-end hs-block-start-mdata-select))))))
-  (goto-char maxp))
+    (let ((block (hs-block-positions)))
+      (setq beg (point) end (cadr block))))
+
+  ;; Show all blocks in that region
+  (unless hs-allow-nesting (hs-discard-overlays beg end))
+
+  ;; Skip initial block
+  (goto-char (1+ beg))
+
+  (while (funcall hs-find-next-block-function hs-block-start-regexp end nil)
+    (if (> arg 1)
+	(hs-hide-level-recursive (1- arg))
+      ;; `hs-hide-block-at-point' already moves the cursor, but if it
+      ;; fails, return to the previous position where we were.
+      (unless (and (goto-char (match-beginning hs-block-start-mdata-select))
+	           (hs-hide-block-at-point t))
+        (goto-char (match-end hs-block-start-mdata-select)))))
+
+  (goto-char end))
 
 (defmacro hs-life-goes-on (&rest body)
   "Evaluate BODY forms if variable `hs-minor-mode' is non-nil.
@@ -1442,6 +1457,57 @@ hs-hide-initial-comment-block
          (when (hs-hideable-region-p beg end)
            (hs-hide-comment-region beg end)))))))
 
+(defun hs-cycle (&optional level)
+  "Cycle the visibility state of the current block.
+This cycles the visibility of the current block between hide the parent
+block, hide the nested blocks only, and show the parent and nested
+blocks.
+
+If LEVEL is specified (interactively, the prefix numeric argument), hide
+only blocks which are that many levels below the level of point."
+  (interactive "p")
+  (hs-life-goes-on
+   ;; Find a block first.
+   (when (or (and (funcall hs-looking-at-block-start-predicate)
+                  (hs-hideable-region-p))
+             (and (goto-char (line-beginning-position))
+                  (funcall hs-find-block-beginning-function)))
+     (if (> level 1)
+         (hs-hide-level-recursive level)
+       (let* (hs-allow-nesting
+              (block (hs-block-positions))
+              (ov (seq-find
+                   (lambda (o)
+                     (and (eq (overlay-get o 'invisible) 'hs)))
+                   (overlays-in (car block) (cadr block)))))
+         (if (and (save-excursion
+                    (funcall hs-find-next-block-function
+                             hs-block-start-regexp (cadr block) nil)))
+             (cond
+              ;; Hide all if there are no hidden blocks
+              ((not ov) (hs-hide-block))
+              ;; Hide the children blocks if the parent block is hidden
+              ((and (= (overlay-start ov) (car block))
+                    (= (overlay-end ov) (cadr block)))
+               (hs-hide-level-recursive 1))
+              ;; Otherwise show all in the parent block, we cannot use
+              ;; `hs-show-block' here because we already know the
+              ;; positions.
+              (ov (hs-discard-overlays (car block) (cadr block))
+                  (run-hooks 'hs-show-hook)))
+           ;; If there are not children blocks, only toggle the
+           ;; visibility.
+           (hs-toggle-hiding)))))))
+
+(defun hs-toggle-all ()
+  "Hide or show all the blocks in the current buffer."
+  (interactive)
+  (if hs--toggle-all-state
+      (let (hs-allow-nesting)
+        (hs-discard-overlays (point-min) (point-max)))
+    (hs-hide-all))
+  (setq-local hs--toggle-all-state (not hs--toggle-all-state)))
+
 ;;;###autoload
 (define-minor-mode hs-minor-mode
   "Minor mode to selectively hide/show code and comment blocks.
-- 
2.51.1


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


-- 
- E.G via Gnus and Org.

--=-=-=--




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

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


Received: (at 79877) by debbugs.gnu.org; 28 Nov 2025 07:19:24 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Nov 28 02:19:24 2025
Received: from localhost ([127.0.0.1]:44070 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vOslI-00008J-2K
	for submit <at> debbugs.gnu.org; Fri, 28 Nov 2025 02:19:24 -0500
Received: from mout-p-101.mailbox.org ([80.241.56.151]:59828)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1vOslE-00007q-Ft
 for 79877 <at> debbugs.gnu.org; Fri, 28 Nov 2025 02:19:21 -0500
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 4dHl6851vPz9tHc;
 Fri, 28 Nov 2025 08:19:12 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linkov.net; s=MBO0001; 
 t=1764314352;
 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=H8CHF5yohiVLuKi2ycH6gUIaq3tq1MwT/OdddRY/ays=;
 b=aN7mXGl7r81VtKMZvp47pxR7KEuIAPDkeMn3dVOo8C8tM7GVwQdibrEMtQhXSiY+WPBqZU
 3ALnFQesRplDaUgcbWsTT54Q+bhtWczGviwzfANHRIj3qURIFLVoHNQBwQ1r5hlVZF2/qL
 9q9HVk0hI+0cYeQ9WPdC0JexwwIpTfqssszPP2auZclpJWWYiweNavXlrL+xEsPJJCbRDS
 lOlVWwqhJxM6+39i338j7+Sc4fJ8LdPyhZy14NruEiNl+cdbqQALApUqoDAJZhA55uZIjh
 vxcreW5Sxvtx3FgKRCgZ994Y+yXfQnlLYo1cb5dFlDbZU7DJiBLRrwEjDUGPUg==
From: Juri Linkov <juri@HIDDEN>
To: Eli Zaretskii <eliz@HIDDEN>
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
In-Reply-To: <86ecpiaayn.fsf@HIDDEN>
Organization: LINKOV.NET
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
 <87bjko17fi.fsf@HIDDEN> <86ikewasy0.fsf@HIDDEN>
 <87fr9zw7oz.fsf@HIDDEN> <86ecpiaayn.fsf@HIDDEN>
Date: Fri, 28 Nov 2025 09:17:50 +0200
Message-ID: <87ecpiy6ap.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79877
Cc: 79877 <at> debbugs.gnu.org,
 Elijah Gabe =?iso-8859-1?Q?P=E9rez?= <eg642616@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 (-)

>> >> +  "C-TAB"   #'hs-cycle
>> >> +  "C-S-TAB" #'hs-toggle-all)
>> >
>> > These bindings are problematic, because they won't work on text-only
>> > terminals, at least some of them.  Can we come up with either
>> > alternative or additional bindings that could be used on TTYs?
>> 
>> I prefer adding additional bindings, but I don't know which ones to use.
>
> Juri (or anyone else), any suggestions?

Maybe

C-c @ TAB
C-c @ S-TAB




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

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


Received: (at 79877) by debbugs.gnu.org; 28 Nov 2025 07:11:06 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Nov 28 02:11:06 2025
Received: from localhost ([127.0.0.1]:44002 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vOsdG-0005Ok-4O
	for submit <at> debbugs.gnu.org; Fri, 28 Nov 2025 02:11:06 -0500
Received: from eggs.gnu.org ([2001:470:142:3::10]:42414)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <eliz@HIDDEN>) id 1vOsdE-0005OB-PR
 for 79877 <at> debbugs.gnu.org; Fri, 28 Nov 2025 02:11:05 -0500
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 1vOsd9-0005Da-5W; Fri, 28 Nov 2025 02:10:59 -0500
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=IOfOys9xrFco8DY1PHd3lKCNA48yru+/bH5I74aGMoU=; b=r3sJ3Elj4wsUzFOXGdHn
 pw0dGhu/85cf+CEPC0uXVXPL38vVcbFfgOLjArRD1Aba1SOx6PcTNFViCVYw/ciGTEOn2T0rSlJTr
 5pJ93Ii0xvM3BOmtoTll9DoRAgteY0sQvjP++BT5DjIX6juJuG3nNEK8DvgCUXl7hhXveNRElNFIE
 vorhEsYGyrC6avigxyHnJ2BRzy1BmaKk5rcIwAvLARcuR4oHlqcdKAtJiqwarxAFNK2YY1jLEnXb9
 ygvyJnMP9z3Fxn7ZTiBSU0epez3OhKb1kZrdGYQ7NQU3uZL+KrnYlFRIgQ1mzWd/YiAdvjbZhG0yh
 s+pVMNM8/8HqzQ==;
Date: Fri, 28 Nov 2025 09:10:56 +0200
Message-Id: <86ecpiaayn.fsf@HIDDEN>
From: Eli Zaretskii <eliz@HIDDEN>
To: Elijah Gabe =?utf-8?Q?P=C3=A9rez?= <eg642616@HIDDEN>, Juri Linkov
 <juri@HIDDEN>
In-Reply-To: <87fr9zw7oz.fsf@HIDDEN> (message from Elijah Gabe
 =?utf-8?Q?P=C3=A9rez?= on Thu, 27 Nov 2025 14:18:20 -0600)
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
 <87bjko17fi.fsf@HIDDEN> <86ikewasy0.fsf@HIDDEN>
 <87fr9zw7oz.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: 79877
Cc: 79877 <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: -3.3 (---)

> From: Elijah Gabe Pérez <eg642616@HIDDEN>
> Cc: 79877 <at> debbugs.gnu.org
> Date: Thu, 27 Nov 2025 14:18:20 -0600
> 
> Eli Zaretskii <eliz@HIDDEN> writes:
> 
> >> From: Elijah Gabe Pérez <eg642616@HIDDEN>
> >> Date: Wed, 26 Nov 2025 21:27:29 -0600
> >> 
> >> +  "C-TAB"   #'hs-cycle
> >> +  "C-S-TAB" #'hs-toggle-all)
> >
> > These bindings are problematic, because they won't work on text-only
> > terminals, at least some of them.  Can we come up with either
> > alternative or additional bindings that could be used on TTYs?
> 
> I prefer adding additional bindings, but I don't know which ones to use.

Juri (or anyone else), any suggestions?

> >> +  ;; If we are near of a block, set MINP and MAXP according to that
> >> +  ;; block positions.
> >>    (when (funcall hs-find-block-beginning-function)
> >> -    (setq minp (1+ (point)))
> >> -    (funcall hs-forward-sexp-function 1)
> >> -    (setq maxp (1- (point))))
> >> -  (unless hs-allow-nesting
> >> -    (hs-discard-overlays minp maxp))
> >> -  (goto-char minp)
> >> +    (let ((block (hs-block-positions)))
> >> +      (setq minp (point) maxp (cadr block))))
> >
> > Seems to completely ignore MINP and MAXP, even if they are specified,
> > at least in some cases.  Or what did I miss?
> 
> MINP and MAXP are only used if point is not inside or behind of a block,
> in that case it will only hide N levels in all the blocks of the current
> buffer.
> 
> I don't know why `hs-hide-level-recursive` is designed that way.

That's fine, but the doc string should mention that these arguments
are not used, even if specified, if point is inside a block.

Thanks.




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

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


Received: (at 79877) by debbugs.gnu.org; 27 Nov 2025 20:18:36 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Nov 27 15:18:36 2025
Received: from localhost ([127.0.0.1]:37713 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vOiRn-0004Al-Ag
	for submit <at> debbugs.gnu.org; Thu, 27 Nov 2025 15:18:36 -0500
Received: from mail-ot1-x342.google.com ([2607:f8b0:4864:20::342]:61889)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vOiRk-0004AR-Du
 for 79877 <at> debbugs.gnu.org; Thu, 27 Nov 2025 15:18:33 -0500
Received: by mail-ot1-x342.google.com with SMTP id
 46e09a7af769-7c6da5e3353so828590a34.3
 for <79877 <at> debbugs.gnu.org>; Thu, 27 Nov 2025 12:18:32 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1764274706; x=1764879506; 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=zYlgrbfypSPWuVj44e7vlyYzwPQG9dKpxQozSU8U0y0=;
 b=bFwBEh7Sku25xCcMnBKI2W2IOHr4L3ecv4x2Y3QAhH1qTdZ5CCdQeFcwU9e9e44roQ
 ZsHWXsRqbWX14NVBZHZhnqqLZxs9CMnm80gh71BGbdMD6KwK92CE54aQA3XRFrUCTtx4
 VEKaDOcqVchYFbPrrMb2ROXDEVr6fQsRg4Xuiw7nXk2rwIxsUjgmog+tEDHZYnvrK1hD
 pAVaFkkB8Mo1MbOy+nsoUyzq80TF0LWdc2y9vPxXE10Hutlhw8K1BCPuoxG+WXOM2L18
 t4EP28j1Um2PYGe8fx+snmiL2GqlrUWsJ1KmnW2hSN8ir04QdKN4sLc2DmOZaEwbpMyU
 HVEQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1764274706; x=1764879506;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject
 :date:message-id:reply-to;
 bh=zYlgrbfypSPWuVj44e7vlyYzwPQG9dKpxQozSU8U0y0=;
 b=Y6X9ztEhjePZViLby/g5F0vTSzN7H8wtBVGuN3kylOQO/s47iuBD43kxBzye0wphSd
 xrdDZ4MZfvBJKAK2WQi13aNPXKLDGfLq540XnpdBbU1GhwXO6yMlmKWyN61201hznfZd
 STWrWaYCzTv1o6qkMqkrTbtH2YFxxF6fScnP/hGUIyEWm6oa2HaoRUEeDe9CEhEmjWby
 RZp6GBrC0rP5r+aQtanrtI+n2OrBL4B65RoG2O6gqFMc/LRwbgDKXewW6AdOvkN+s3TD
 PqvrXdf3ATwGNL78Fc6Wesg1r/dd8GtGmQQX5CaK/e7aZOHWyDIete2UydCcvB+HCIry
 JJwA==
X-Gm-Message-State: AOJu0YyO6uKdXtsGVCGAIUhFBTJcmszflK3QHKAHKiokwWElzft0i9Ru
 0d6o4tR2XwSczBKVzkfQB70edxWpMEyyHi7Hwief7z13nsM9w+HpLDegLSwOOtfz
X-Gm-Gg: ASbGnctlcmCgHrQkmJ+ys8K10l31Sd9/jxuWTvgSz6mIGK3axyJLCGmTKbTCbBRl/ZU
 GdmB3J1bf7ZoIbihSs4V/3SLRhGQbV3uGJiF1bmdj/RlvfeDVC+LTb8Gkj65PCxgPONJdneJrvK
 B47MtUN8Tx2r23l/3BEVsYNcliDkNWX2yWSmqapQqcOYWRcmPJCjzJ/VhGVFQnqpugbaqLn3Bj/
 9YM5uvf/eFriULWZbkc7FH2tB9CpXAM+YjBeNqesPFNgKQ7EjztTSWiTaonDNRBVOT5Js4o4o58
 ysAhcEuRXAcp+CbPdXjICntyOxjMfXdw35GjQyDEUQQymvZGXD6CZN20kMjUKlKXlFS/+sgumO5
 v0safNRZM8VS6anecZkv5vde2bBnbHWDLRgRFrWBd/GYNHrN+oFOj2GcRIQcqhZ7GJ1YfjDjxO+
 vYdpSVydfSvQ7nHBQ=
X-Google-Smtp-Source: AGHT+IHbXQz9EURoMjiDqYo4D1ewFPAg5+o+MyYV+HdZcExyVkkkvg5lfvHj4aOQQGnZmV1DBTT1GA==
X-Received: by 2002:a05:6830:6505:b0:799:de78:29d1 with SMTP id
 46e09a7af769-7c7c417818dmr5304743a34.15.1764274706170; 
 Thu, 27 Nov 2025 12:18:26 -0800 (PST)
Received: from fedora ([189.215.160.233]) by smtp.gmail.com with ESMTPSA id
 46e09a7af769-7c910025f8bsm851993a34.29.2025.11.27.12.18.22
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Thu, 27 Nov 2025 12:18:25 -0800 (PST)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: Eli Zaretskii <eliz@HIDDEN>
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
In-Reply-To: <86ikewasy0.fsf@HIDDEN>
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
 <87bjko17fi.fsf@HIDDEN> <86ikewasy0.fsf@HIDDEN>
Date: Thu, 27 Nov 2025 14:18:20 -0600
Message-ID: <87fr9zw7oz.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: 79877
Cc: 79877 <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; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Eli Zaretskii <eliz@HIDDEN> writes:

>> From: Elijah Gabe P=C3=A9rez <eg642616@HIDDEN>
>> Date: Wed, 26 Nov 2025 21:27:29 -0600
>>=20
>> +  "C-TAB"   #'hs-cycle
>> +  "C-S-TAB" #'hs-toggle-all)
>
> These bindings are problematic, because they won't work on text-only
> terminals, at least some of them.  Can we come up with either
> alternative or additional bindings that could be used on TTYs?

I prefer adding additional bindings, but I don't know which ones to use.

>> +(defun hs-hide-level-recursive (arg &optional minp maxp)
>> +  "Recursively hide blocks ARG levels below point in region (MINP MAXP).
>
> Since this function doesn't use the region, I would suggest to omit
> the reference to "region" from the first line.  Like this:
>
>   Recursively hide blocks between MINP and MAXP that are ARG levels below=
 point.
>
> (This rewording also removes the ambiguity wrt whether "in region"
> refers to point or to blocks.)
>
> I also suggest to rename the arguments to BEG and END, as that makes
> their function more clear.

Thanks, i've fixed it.

>> +If MINP and MAXP are not specified, it will search for a near block and
>> +use its position instead."
>
> This might benefit from a more detailed description of what is meant
> by "search for a near block".  Is that the block to which point
> belongs?  Or maybe the first block that begins before point?  Or
> something else?

It is the block to which point belongs.

> Btw, the code:
>
>> +  ;; If we are near of a block, set MINP and MAXP according to that
>> +  ;; block positions.
>>    (when (funcall hs-find-block-beginning-function)
>> -    (setq minp (1+ (point)))
>> -    (funcall hs-forward-sexp-function 1)
>> -    (setq maxp (1- (point))))
>> -  (unless hs-allow-nesting
>> -    (hs-discard-overlays minp maxp))
>> -  (goto-char minp)
>> +    (let ((block (hs-block-positions)))
>> +      (setq minp (point) maxp (cadr block))))
>
> Seems to completely ignore MINP and MAXP, even if they are specified,
> at least in some cases.  Or what did I miss?

MINP and MAXP are only used if point is not inside or behind of a block,
in that case it will only hide N levels in all the blocks of the current
buffer.

I don't know why `hs-hide-level-recursive` is designed that way.

>> +(defun hs-cycle (&optional level)
>> +  "Cycle the visibility state of the current block.
>> +With argument, hide only the LEVEL levels below point"
>
> Our style is to say
>
>    If LEVEL is specified (interactively, the prefix numeric argument),
>    hide only blocks which are that many levels below the level of point.

Thanks, i've fixed it too.


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow.el-New-commands-hs-cycle-and-hs-toggle-all.patch

From 1883d356856a2088e5b7b80f4db2f7f821081560 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Thu, 18 Sep 2025 19:24:53 -0600
Subject: [PATCH] hideshow.el: New commands 'hs-cycle' and 'hs-toggle-all'

bug#79877

* etc/NEWS: Announce features.
* doc/emacs/programs.texi (Hideshow): Document it.
* lisp/progmodes/hideshow.el (hs-prefix-map): Bind the new
commands.
(hs-hide-level-recursive): Simplify.
(hs--toggle-all-state): New variable.
(hs-toggle-all, hs-cycle): New commands.

Co-authored-by: Karthik Chikmagalur <karthikchikmagalur@HIDDEN>
---
 doc/emacs/programs.texi    |   7 +++
 etc/NEWS                   |  10 ++++
 lisp/progmodes/hideshow.el | 120 ++++++++++++++++++++++++++++---------
 3 files changed, 108 insertions(+), 29 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 0adb90b36cb..ad241470b5c 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1699,6 +1699,7 @@ Hideshow
 @findex hs-show-region
 @findex hs-hide-level
 @findex hs-toggle-hiding
+@findex hs-cycle
 @kindex C-c @@ C-h
 @kindex C-c @@ C-s
 @kindex C-c @@ C-c
@@ -1706,6 +1707,8 @@ Hideshow
 @kindex C-c @@ C-M-s
 @kindex C-c @@ C-r
 @kindex C-c @@ C-l
+@kindex C-c @@ C-TAB
+@kindex C-c @@ C-S-TAB
 @kindex S-mouse-2
 @table @kbd
 @item C-c @@ C-h
@@ -1726,6 +1729,10 @@ Hideshow
 @item C-u @var{n} C-c @@ C-l
 Hide all blocks @var{n} levels below this block
 (@code{hs-hide-level}).
+@item C-c @@ C-TAB
+Cycle the visibility state of the current block (@code{hs-cycle}).
+@item C-c @@ C-S-TAB
+Either hide or show all the blocks in the current buffer. (@code{hs-toggle-all}).
 @end table
 
 @vindex hs-hide-comments-when-hiding-all
diff --git a/etc/NEWS b/etc/NEWS
index 7d132356484..108ad599ef8 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1082,6 +1082,16 @@ convention (regexp arg second) and Emacs convention (regexp arg first).
 
 ** Hideshow
 
++++
+*** New command 'hs-cycle'.
+This command cycles the visibility state of the current block between
+hide the parent block, hide the nested blocks only and show all the
+blocks.
+
++++
+*** New command 'hs-toggle-all'.
+This command hide or show all the blocks in the current buffer.
+
 +++
 *** New user option 'hs-display-lines-hidden'.
 If this option is non-nil, Hideshow displays the number of hidden lines
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index ac0c68a0410..63a60721b50 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -39,6 +39,8 @@
 ;;   `hs-toggle-hiding'                   C-c @ C-c
 ;;   `hs-toggle-hiding'                   S-<mouse-2>
 ;;   `hs-hide-initial-comment-block'
+;;   `hs-cycle'                           C-c @ C-TAB
+;;   `hs-toggle-all'                      C-c @ C-S-TAB
 ;;
 ;; All these commands are defined in `hs-prefix-map',
 ;; `hs-minor-mode-map' and `hs-indicators-map'.
@@ -504,16 +506,18 @@ hs-prefix-map
   :doc "Keymap for hideshow commands."
   :prefix t
   ;; These bindings roughly imitate those used by Outline mode.
-  "C-h"   #'hs-hide-block
-  "C-s"   #'hs-show-block
-  "C-M-h" #'hs-hide-all
-  "C-M-s" #'hs-show-all
-  "C-l"   #'hs-hide-level
-  "C-c"   #'hs-toggle-hiding
-  "C-a"   #'hs-show-all
-  "C-t"   #'hs-hide-all
-  "C-d"   #'hs-hide-block
-  "C-e"   #'hs-toggle-hiding)
+  "C-h"     #'hs-hide-block
+  "C-d"     #'hs-hide-block
+  "C-s"     #'hs-show-block
+  "C-M-h"   #'hs-hide-all
+  "C-t"     #'hs-hide-all
+  "C-M-s"   #'hs-show-all
+  "C-a"     #'hs-show-all
+  "C-l"     #'hs-hide-level
+  "C-c"     #'hs-toggle-hiding
+  "C-e"     #'hs-toggle-hiding
+  "C-TAB"   #'hs-cycle
+  "C-S-TAB" #'hs-toggle-all)
 
 (defvar-keymap hs-minor-mode-map
   :doc "Keymap for hideshow minor mode."
@@ -1184,26 +1188,32 @@ hs-find-next-block
   (and (< (point) maxp)
        (re-search-forward regexp maxp t)))
 
-(defun hs-hide-level-recursive (arg minp maxp)
-  "Recursively hide blocks ARG levels below point in region (MINP MAXP)."
+(defun hs-hide-level-recursive (arg &optional beg end)
+  "Recursively hide blocks between BEG and END that are ARG levels below point.
+If BEG and END are not specified, it will search for a near block and
+use its position instead."
+  ;; If we are near of a block, set BEG and END according to that
+  ;; block positions.
   (when (funcall hs-find-block-beginning-function)
-    (setq minp (1+ (point)))
-    (funcall hs-forward-sexp-function 1)
-    (setq maxp (1- (point))))
-  (unless hs-allow-nesting
-    (hs-discard-overlays minp maxp))
-  (goto-char minp)
-  (while (funcall hs-find-next-block-function hs-block-start-regexp maxp nil)
-    (when (save-match-data
-	    (not (nth 8 (syntax-ppss)))) ; not inside comments or strings
-      (if (> arg 1)
-	  (hs-hide-level-recursive (1- arg) minp maxp)
-        ;; `hs-hide-block-at-point' already moves the cursor, but if it
-        ;; fails, return to the previous position where we were.
-	(unless (and (goto-char (match-beginning hs-block-start-mdata-select))
-	             (hs-hide-block-at-point t))
-            (goto-char (match-end hs-block-start-mdata-select))))))
-  (goto-char maxp))
+    (let ((block (hs-block-positions)))
+      (setq beg (point) end (cadr block))))
+
+  ;; Show all blocks in that region
+  (unless hs-allow-nesting (hs-discard-overlays beg end))
+
+  ;; Skip initial block
+  (goto-char (1+ beg))
+
+  (while (funcall hs-find-next-block-function hs-block-start-regexp end nil)
+    (if (> arg 1)
+	(hs-hide-level-recursive (1- arg))
+      ;; `hs-hide-block-at-point' already moves the cursor, but if it
+      ;; fails, return to the previous position where we were.
+      (unless (and (goto-char (match-beginning hs-block-start-mdata-select))
+	           (hs-hide-block-at-point t))
+        (goto-char (match-end hs-block-start-mdata-select)))))
+
+  (goto-char end))
 
 (defmacro hs-life-goes-on (&rest body)
   "Evaluate BODY forms if variable `hs-minor-mode' is non-nil.
@@ -1442,6 +1452,58 @@ hs-hide-initial-comment-block
          (when (hs-hideable-region-p beg end)
            (hs-hide-comment-region beg end)))))))
 
+(defun hs-cycle (&optional level)
+  "Cycle the visibility state of the current block.
+This cycles the visibility of the current block between hide the parent
+block, hide the nested blocks only, and show the parent and nested
+blocks.
+
+If LEVEL is specified (interactively, the prefix numeric argument), hide
+only blocks which are that many levels below the level of point."
+  (interactive "p")
+  (hs-life-goes-on
+   ;; Find a block first.
+   (when (or (and (funcall hs-looking-at-block-start-predicate)
+                  (hs-hideable-region-p))
+             (and (goto-char (line-beginning-position))
+                  (funcall hs-find-block-beginning-function)))
+     (if (> level 1) (hs-hide-level-recursive level)
+       (let* (hs-allow-nesting
+              (block (hs-block-positions))
+              (ov (seq-find
+                   (lambda (o)
+                     (and (eq (overlay-get o 'invisible) 'hs)))
+                   (overlays-in (car block) (cadr block)))))
+         (if (and (save-excursion
+                    (funcall hs-find-next-block-function
+                             hs-block-start-regexp (cadr block) nil)))
+             (cond
+              ;; Hide all if there are no hidden blocks
+              ((not ov) (hs-hide-block))
+              ;; Hide the children blocks if the parent block is hidden
+              ((and (= (overlay-start ov) (car block))
+                    (= (overlay-end ov) (cadr block)))
+               (hs-hide-level-recursive 1))
+              ;; Otherwise show all in the parent block, we cannot use
+              ;; `hs-show-block' here because we already know the
+              ;; positions.
+              (ov (hs-discard-overlays (car block) (cadr block))
+                  (run-hooks 'hs-show-hook)))
+           ;; If there are not children blocks, only toggle the
+           ;; visibility.
+           (hs-toggle-hiding)))))))
+
+(defvar-local hs--toggle-all-state)
+
+(defun hs-toggle-all ()
+  "Hide or show all the blocks in the current buffer."
+  (interactive)
+  (if hs--toggle-all-state
+      (let (hs-allow-nesting)
+        (hs-discard-overlays (point-min) (point-max)))
+    (hs-hide-all))
+  (setq-local hs--toggle-all-state (not hs--toggle-all-state)))
+
 ;;;###autoload
 (define-minor-mode hs-minor-mode
   "Minor mode to selectively hide/show code and comment blocks.
-- 
2.51.1


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



-- 
- E.G via Gnus and Org.

--=-=-=--




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

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


Received: (at 79877) by debbugs.gnu.org; 27 Nov 2025 07:27:26 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Nov 27 02:27:26 2025
Received: from localhost ([127.0.0.1]:34067 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vOWPW-0000p8-Bx
	for submit <at> debbugs.gnu.org; Thu, 27 Nov 2025 02:27:26 -0500
Received: from mout.gmx.net ([212.227.15.15]:50997)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <michael.albinus@HIDDEN>)
 id 1vOWPT-0000or-0f
 for 79877 <at> debbugs.gnu.org; Thu, 27 Nov 2025 02:27:24 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmx.de;
 s=s31663417; t=1764228436; x=1764833236; i=michael.albinus@HIDDEN;
 bh=EyyDfyYck82vtDOinxl8gsbdB3BdYFTHzTdAMthUp0U=;
 h=X-UI-Sender-Class:From:To:Cc:Subject:In-Reply-To:References:Date:
 Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:cc:
 content-transfer-encoding:content-type:date:from:message-id:
 mime-version:reply-to:subject:to;
 b=N9NSv5oe+kRQfTc5h4bZEye3rRGTTVMFhPIhAifXwl6k1YpPUELgN9pXxXvvtCXR
 M0vmnujkd73w11szDe7v2q2fqi2XMVcBAItL6qHMr2KgBYMSZ5AxjYgUHeX8CuH0d
 6Gfes0fjc8Zeo65bQLjlEFoXs874J9+5L8vK8J5QuBfWN5gdf0gJdWv6ObaxFjWLA
 viFFpFk1fsZ+Q5a3btURpCpEjkMD/W2+rZmvw/pdIkDDg3zWkKLy+dl3eX4TLzz29
 7dt0uzoHRb171GR2meK0ireOrA0qintDLWyDmbuf2v53R6okJkNkEME1PTfOLrkhF
 bHdD9SXcRwOYpZfoUw==
X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a
Received: from gandalf.gmx.de ([185.89.37.61]) by mail.gmx.net (mrgmx004
 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MWzk3-1vdW1t1crJ-00VnWD; Thu, 27
 Nov 2025 08:27:16 +0100
From: Michael Albinus <michael.albinus@HIDDEN>
To: Elijah Gabe =?utf-8?Q?P=C3=A9rez?= <eg642616@HIDDEN>
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
In-Reply-To: <87bjko17fi.fsf@HIDDEN>
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
 <87bjko17fi.fsf@HIDDEN>
Date: Thu, 27 Nov 2025 08:27:15 +0100
Message-ID: <878qfsylyk.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Provags-ID: V03:K1:kRnRk5dbH3Ixsr2m83DSZP6JZzKp431npjJWAZvwYNv6h4m4vt8
 CllXF3JuFiTkPBKdWXWNCPFhCmzau8hu8zBroUnkZRd2MyT3hysLt8OxwmGYgKJqFMPhMay
 3pVyBNidciog1H1vNEYxB35rMCMynjYDE5zaXFHFSDQIbNVbTuHHYCT3B1ZPn/mhlBb/5IF
 /qHANr22Yi82J0k1A5EkQ==
X-Spam-Flag: NO
UI-OutboundReport: notjunk:1;M01:P0:dVfjv0iI4Zs=;pilmzx5auEmhUGjK29FHkG5L1jp
 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
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 79877
Cc: 79877 <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 (-)

Elijah Gabe P=C3=A9rez <eg642616@HIDDEN> writes:

Hi,

> --- a/etc/NEWS
> +++ b/etc/NEWS
> @@ -1082,6 +1082,11 @@ convention (regexp arg second) and Emacs conventio=
n (regexp arg first).
>=20=20
>  ** Hideshow
>=20=20
> ++++
> +*** New command 'hs-cycle'
> +
> +*** New command 'hs-toggle-all'
> +

The first line must be finished with a trailing period. And for people
like me, not familiar with Hideshow, a further short explanation of the
commands would be needed.

Best regards, Michael.




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

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


Received: (at 79877) by debbugs.gnu.org; 27 Nov 2025 06:30:40 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Nov 27 01:30:40 2025
Received: from localhost ([127.0.0.1]:33766 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vOVWZ-000567-Si
	for submit <at> debbugs.gnu.org; Thu, 27 Nov 2025 01:30:40 -0500
Received: from eggs.gnu.org ([2001:470:142:3::10]:42526)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <eliz@HIDDEN>) id 1vOVWT-00055S-JL
 for 79877 <at> debbugs.gnu.org; Thu, 27 Nov 2025 01:30:37 -0500
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 1vOVWN-00084i-SL; Thu, 27 Nov 2025 01:30:27 -0500
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=BWE2DVx2o+WoE549hDhBnl8Urbgxf6r3qGrElG11rGc=; b=X/L73EVclfCxLK77Cmxj
 ar+Ycd0v/I7pRYZGLeanGqjsd2QkoddHsBU7p118+ZirsSstil/HY+j+94H+GDit6zeX167cDkoP/
 nCqXbZTNA/aDIGRNwvBk1drIcmBQWpA4WzLKYYrTZge1eTymcIJJ0ydxaBMvT5rZrnffSlEXr3Ml5
 wF1MFcJxfwiDry/VxYpXNlQpot88+9AYW5mtQc6s+CG7DSfJvkc9Pv1i/rbjn67wQ1kBYvdT+RzPq
 l9V01zl12rMzdgcpqcbOL8jjl+Oi0RUmJp4EHIhBcDvmw+8pGWwtRAdCj+jDONHDx3EB5IyI/StNh
 ij8gBeNPneOvVQ==;
Date: Thu, 27 Nov 2025 08:30:15 +0200
Message-Id: <86ikewasy0.fsf@HIDDEN>
From: Eli Zaretskii <eliz@HIDDEN>
To: Elijah Gabe =?utf-8?Q?P=C3=A9rez?= <eg642616@HIDDEN>
In-Reply-To: <87bjko17fi.fsf@HIDDEN> (message from Elijah Gabe
 =?utf-8?Q?P=C3=A9rez?= on Wed, 26 Nov 2025 21:27:29 -0600)
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
 <87bjko17fi.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: 79877
Cc: 79877 <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: -3.3 (---)

> From: Elijah Gabe Pérez <eg642616@HIDDEN>
> Date: Wed, 26 Nov 2025 21:27:29 -0600
> 
> +  "C-TAB"   #'hs-cycle
> +  "C-S-TAB" #'hs-toggle-all)

These bindings are problematic, because they won't work on text-only
terminals, at least some of them.  Can we come up with either
alternative or additional bindings that could be used on TTYs?

> +(defun hs-hide-level-recursive (arg &optional minp maxp)
> +  "Recursively hide blocks ARG levels below point in region (MINP MAXP).

Since this function doesn't use the region, I would suggest to omit
the reference to "region" from the first line.  Like this:

  Recursively hide blocks between MINP and MAXP that are ARG levels below point.

(This rewording also removes the ambiguity wrt whether "in region"
refers to point or to blocks.)

I also suggest to rename the arguments to BEG and END, as that makes
their function more clear.

> +If MINP and MAXP are not specified, it will search for a near block and
> +use its position instead."

This might benefit from a more detailed description of what is meant
by "search for a near block".  Is that the block to which point
belongs?  Or maybe the first block that begins before point?  Or
something else?

Btw, the code:

> +  ;; If we are near of a block, set MINP and MAXP according to that
> +  ;; block positions.
>    (when (funcall hs-find-block-beginning-function)
> -    (setq minp (1+ (point)))
> -    (funcall hs-forward-sexp-function 1)
> -    (setq maxp (1- (point))))
> -  (unless hs-allow-nesting
> -    (hs-discard-overlays minp maxp))
> -  (goto-char minp)
> +    (let ((block (hs-block-positions)))
> +      (setq minp (point) maxp (cadr block))))

Seems to completely ignore MINP and MAXP, even if they are specified,
at least in some cases.  Or what did I miss?

> +(defun hs-cycle (&optional level)
> +  "Cycle the visibility state of the current block.
> +With argument, hide only the LEVEL levels below point"

Our style is to say

   If LEVEL is specified (interactively, the prefix numeric argument),
   hide only blocks which are that many levels below the level of point.

Thanks.




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

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


Received: (at 79877) by debbugs.gnu.org; 27 Nov 2025 03:27:47 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Nov 26 22:27:46 2025
Received: from localhost ([127.0.0.1]:60599 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vOSfa-0000w8-6Q
	for submit <at> debbugs.gnu.org; Wed, 26 Nov 2025 22:27:46 -0500
Received: from mail-ot1-x343.google.com ([2607:f8b0:4864:20::343]:59559)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vOSfX-0000vm-13
 for 79877 <at> debbugs.gnu.org; Wed, 26 Nov 2025 22:27:44 -0500
Received: by mail-ot1-x343.google.com with SMTP id
 46e09a7af769-7c7533dbd87so355427a34.2
 for <79877 <at> debbugs.gnu.org>; Wed, 26 Nov 2025 19:27:42 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1764214057; x=1764818857; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=5TBF7+BK50DqhtjJS/0rYNzAJvbdiHkt51WJJW3+CfU=;
 b=LaUGGvCwtDOZTmBpnREUohAaQPnJKJ0QYFt0a5UHW9c+wl4+W1BQaOrji8trqhf644
 ikvhVgI3gty2hGC68Ff6nqhQQo9sDgW3gSSEj0zuJgBMC2j4oiLdsMgcTeBA6PuWwFOv
 uaZ4KgL2VTh29idl3oigLm71yRM6/qABqClgeahbpT9y6cL1KrroN3CX8Zt1kTvL2uxb
 57FiBbAu4JqMMvVIXFeqwm3ZP8Tb1dbnZskZu65IiIbr8TI0DdocLGAZqe8D3Oc0oLKF
 aIDRYZtxVsldsVoBJU7jZ5lrJMBnhwtW5c8IWcOwvffH09TuYVwf0a70V1xGQbNYqW7y
 7y/A==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1764214057; x=1764818857;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=5TBF7+BK50DqhtjJS/0rYNzAJvbdiHkt51WJJW3+CfU=;
 b=YOpKtlt6fZ+g36BJyGy2Asxy61vrdElyb/J1sAFULIfy0cxT84B1JDkUvJPVNMmCpo
 A8LTAH+Skg++6xdjeC53R70c6QfoF+BLBsYpb6y78ietEWJ+ZenOTG5OtBvtlXIdwS0V
 HjX17uaXWVbAAgoH3bmcNS0UkVKo3gZgEhjrXLB9Ukz7Yh99J4WzN+Wj7hENjPzNUh+m
 57cYp4VzC4fUFwdj48dIeiEYOpL1BRVI743RB5fLkq95MgyxI5T7DCZtRDhNgpJex9b8
 7acX/Dd5N77tOEw2xt4xBvlGEAYL6LzzT6rP2bZiT15oYTtNnBlnPAXYHe9hQkuHU/Ym
 cHyw==
X-Gm-Message-State: AOJu0YxGaupYRnSpSIicYPVtW32xKxKrmbDYcUlTl5wGoWIzxMRFwzQH
 dCH33Ho8fSq1dEXGmQ/19RlsVUTTdwhX0J779QtOjziBWeuQkCbObl0LKnEt/G1c
X-Gm-Gg: ASbGncv8s6v9cB2ZhDXmRBIU6yDrn/s7vt1kpgZzXNBlL2N6IGSfK5GW9d+dd+8Ew3t
 rP4pDQb26nUl3+8T0F25To899PX6LEF528KPUutl/R6wvnJKGDtSdz26PDxX6iqesnzs9uHcVPG
 txOCOR1iSrg31WvmzO56akJO4Lc4h0eglmewiz/vAVnaRaHBZbnKwHLrbCfrGgLBMEkdssR26+V
 Dc/HCNIHBTnzsGzukW7ouLIuptwVQigu+oosJGctTElJmiZpWTqAZ2WutEctqL5GAzvtDYLnqUA
 ii+vFbgXexdzut/iQs4/h4wqUlGfOugw4hciB82L6IyUx5XBgIj3iDXp5PHAPfmLjq6GhkVNFwe
 bEIoZzqX9jbkbs22roLbmJ/9ESUrApILpKglYi/f/wmvEjnzBwR+BRyDyx33VIuG+HXS92/q8uH
 RWS1S85Ve1LB/E0Is=
X-Google-Smtp-Source: AGHT+IFjbN6Wb3Fcd+VqttWZQ1TRFRwbYXOb0P//gcAnViMCGKZ6qUNbyujzX8JHia7FAwEzf1RXvQ==
X-Received: by 2002:a05:6830:2645:b0:7c5:3afb:79db with SMTP id
 46e09a7af769-7c7c445f9d6mr3375150a34.35.1764214056653; 
 Wed, 26 Nov 2025 19:27:36 -0800 (PST)
Received: from fedora ([189.215.160.233]) by smtp.gmail.com with ESMTPSA id
 46e09a7af769-7c90f5d7d82sm193780a34.6.2025.11.26.19.27.32
 for <79877 <at> debbugs.gnu.org>
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Wed, 26 Nov 2025 19:27:35 -0800 (PST)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: 79877 <at> debbugs.gnu.org
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
In-Reply-To: <871pll1mb6.fsf@HIDDEN>
References: <87pl9a3lzr.fsf@HIDDEN> <871pll1mb6.fsf@HIDDEN>
Date: Wed, 26 Nov 2025 21:27:29 -0600
Message-ID: <87bjko17fi.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: 79877
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; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Elijah Gabe P=C3=A9rez <eg642616@HIDDEN> writes:

I've updated the patch, now it should work properly.


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow.el-New-commands-hs-cycle-and-hs-toggle-all.patch

From c71f8d210dfd2902637d292f1145d149e860fd66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Thu, 18 Sep 2025 19:24:53 -0600
Subject: [PATCH] hideshow.el: New commands 'hs-cycle' and 'hs-toggle-all'

bug#79877

* etc/NEWS: Announce features.
* doc/emacs/programs.texi (Hideshow): Document it.
* lisp/progmodes/hideshow.el (hs-prefix-map): Bind 'hs-cycle' to
"C-TAB" and 'hs-toggle-all' to "C-S-TAB".
(hs-hide-level-recursive): Simplify.
(hs--toggle-all-state): New variable.
(hs-toggle-all, hs-cycle): New commands.

Co-authored-by: Karthik Chikmagalur <karthikchikmagalur@HIDDEN>
---
 doc/emacs/programs.texi    |   7 +++
 etc/NEWS                   |   5 ++
 lisp/progmodes/hideshow.el | 111 ++++++++++++++++++++++++++++---------
 3 files changed, 96 insertions(+), 27 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 0adb90b36cb..ad241470b5c 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1699,6 +1699,7 @@ Hideshow
 @findex hs-show-region
 @findex hs-hide-level
 @findex hs-toggle-hiding
+@findex hs-cycle
 @kindex C-c @@ C-h
 @kindex C-c @@ C-s
 @kindex C-c @@ C-c
@@ -1706,6 +1707,8 @@ Hideshow
 @kindex C-c @@ C-M-s
 @kindex C-c @@ C-r
 @kindex C-c @@ C-l
+@kindex C-c @@ C-TAB
+@kindex C-c @@ C-S-TAB
 @kindex S-mouse-2
 @table @kbd
 @item C-c @@ C-h
@@ -1726,6 +1729,10 @@ Hideshow
 @item C-u @var{n} C-c @@ C-l
 Hide all blocks @var{n} levels below this block
 (@code{hs-hide-level}).
+@item C-c @@ C-TAB
+Cycle the visibility state of the current block (@code{hs-cycle}).
+@item C-c @@ C-S-TAB
+Either hide or show all the blocks in the current buffer. (@code{hs-toggle-all}).
 @end table
 
 @vindex hs-hide-comments-when-hiding-all
diff --git a/etc/NEWS b/etc/NEWS
index 7d132356484..e61b81a2b7e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1082,6 +1082,11 @@ convention (regexp arg second) and Emacs convention (regexp arg first).
 
 ** Hideshow
 
++++
+*** New command 'hs-cycle'
+
+*** New command 'hs-toggle-all'
+
 +++
 *** New user option 'hs-display-lines-hidden'.
 If this option is non-nil, Hideshow displays the number of hidden lines
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index ac0c68a0410..e5d6c96e9f6 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -39,6 +39,8 @@
 ;;   `hs-toggle-hiding'                   C-c @ C-c
 ;;   `hs-toggle-hiding'                   S-<mouse-2>
 ;;   `hs-hide-initial-comment-block'
+;;   `hs-cycle'                           C-c @ C-TAB
+;;   `hs-toggle-all'                      C-c @ C-S-TAB
 ;;
 ;; All these commands are defined in `hs-prefix-map',
 ;; `hs-minor-mode-map' and `hs-indicators-map'.
@@ -504,16 +506,18 @@ hs-prefix-map
   :doc "Keymap for hideshow commands."
   :prefix t
   ;; These bindings roughly imitate those used by Outline mode.
-  "C-h"   #'hs-hide-block
-  "C-s"   #'hs-show-block
-  "C-M-h" #'hs-hide-all
-  "C-M-s" #'hs-show-all
-  "C-l"   #'hs-hide-level
-  "C-c"   #'hs-toggle-hiding
-  "C-a"   #'hs-show-all
-  "C-t"   #'hs-hide-all
-  "C-d"   #'hs-hide-block
-  "C-e"   #'hs-toggle-hiding)
+  "C-h"     #'hs-hide-block
+  "C-d"     #'hs-hide-block
+  "C-s"     #'hs-show-block
+  "C-M-h"   #'hs-hide-all
+  "C-t"     #'hs-hide-all
+  "C-M-s"   #'hs-show-all
+  "C-a"     #'hs-show-all
+  "C-l"     #'hs-hide-level
+  "C-c"     #'hs-toggle-hiding
+  "C-e"     #'hs-toggle-hiding
+  "C-TAB"   #'hs-cycle
+  "C-S-TAB" #'hs-toggle-all)
 
 (defvar-keymap hs-minor-mode-map
   :doc "Keymap for hideshow minor mode."
@@ -1184,25 +1188,31 @@ hs-find-next-block
   (and (< (point) maxp)
        (re-search-forward regexp maxp t)))
 
-(defun hs-hide-level-recursive (arg minp maxp)
-  "Recursively hide blocks ARG levels below point in region (MINP MAXP)."
+(defun hs-hide-level-recursive (arg &optional minp maxp)
+  "Recursively hide blocks ARG levels below point in region (MINP MAXP).
+If MINP and MAXP are not specified, it will search for a near block and
+use its position instead."
+  ;; If we are near of a block, set MINP and MAXP according to that
+  ;; block positions.
   (when (funcall hs-find-block-beginning-function)
-    (setq minp (1+ (point)))
-    (funcall hs-forward-sexp-function 1)
-    (setq maxp (1- (point))))
-  (unless hs-allow-nesting
-    (hs-discard-overlays minp maxp))
-  (goto-char minp)
+    (let ((block (hs-block-positions)))
+      (setq minp (point) maxp (cadr block))))
+
+  ;; Show all blocks in that region
+  (unless hs-allow-nesting (hs-discard-overlays minp maxp))
+
+  ;; Skip initial block
+  (goto-char (1+ minp))
+
   (while (funcall hs-find-next-block-function hs-block-start-regexp maxp nil)
-    (when (save-match-data
-	    (not (nth 8 (syntax-ppss)))) ; not inside comments or strings
-      (if (> arg 1)
-	  (hs-hide-level-recursive (1- arg) minp maxp)
-        ;; `hs-hide-block-at-point' already moves the cursor, but if it
-        ;; fails, return to the previous position where we were.
-	(unless (and (goto-char (match-beginning hs-block-start-mdata-select))
-	             (hs-hide-block-at-point t))
-            (goto-char (match-end hs-block-start-mdata-select))))))
+    (if (> arg 1)
+	(hs-hide-level-recursive (1- arg))
+      ;; `hs-hide-block-at-point' already moves the cursor, but if it
+      ;; fails, return to the previous position where we were.
+      (unless (and (goto-char (match-beginning hs-block-start-mdata-select))
+	           (hs-hide-block-at-point t))
+        (goto-char (match-end hs-block-start-mdata-select)))))
+
   (goto-char maxp))
 
 (defmacro hs-life-goes-on (&rest body)
@@ -1442,6 +1452,53 @@ hs-hide-initial-comment-block
          (when (hs-hideable-region-p beg end)
            (hs-hide-comment-region beg end)))))))
 
+(defun hs-cycle (&optional level)
+  "Cycle the visibility state of the current block.
+With argument, hide only the LEVEL levels below point"
+  (interactive "p")
+  (hs-life-goes-on
+   ;; Find a block first.
+   (when (or (and (funcall hs-looking-at-block-start-predicate)
+                  (hs-hideable-region-p))
+             (and (goto-char (line-beginning-position))
+                  (funcall hs-find-block-beginning-function)))
+     (if (> level 1) (hs-hide-level-recursive level)
+       (let* (hs-allow-nesting
+              (block (hs-block-positions))
+              (ov (seq-find
+                   (lambda (o)
+                     (and (eq (overlay-get o 'invisible) 'hs)))
+                   (overlays-in (car block) (cadr block)))))
+         (if (and (save-excursion
+                    (funcall hs-find-next-block-function
+                             hs-block-start-regexp (cadr block) nil)))
+             (cond
+              ;; Hide all if there are no hidden blocks
+              ((not ov) (hs-hide-block))
+              ;; Hide the children blocks if the parent block is hidden
+              ((and (= (overlay-start ov) (car block))
+                    (= (overlay-end ov) (cadr block)))
+               (hs-hide-level-recursive 1))
+              ;; Otherwise show all in the parent block, we cannot use
+              ;; `hs-show-block' here because we already know the
+              ;; positions.
+              (ov (hs-discard-overlays (car block) (cadr block))
+                  (run-hooks 'hs-show-hook)))
+           ;; If there are not children blocks, only toggle the
+           ;; visibility.
+           (hs-toggle-hiding)))))))
+
+(defvar-local hs--toggle-all-state)
+
+(defun hs-toggle-all ()
+  "Hide or show all the blocks in the current buffer."
+  (interactive)
+  (if hs--toggle-all-state
+      (let (hs-allow-nesting)
+        (hs-discard-overlays (point-min) (point-max)))
+    (hs-hide-all))
+  (setq-local hs--toggle-all-state (not hs--toggle-all-state)))
+
 ;;;###autoload
 (define-minor-mode hs-minor-mode
   "Minor mode to selectively hide/show code and comment blocks.
-- 
2.51.1


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


-- 
- E.G via Gnus and Org.

--=-=-=--




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

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


Received: (at 79877) by debbugs.gnu.org; 26 Nov 2025 03:54:04 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Nov 25 22:54:04 2025
Received: from localhost ([127.0.0.1]:47650 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vO6bU-00065y-0R
	for submit <at> debbugs.gnu.org; Tue, 25 Nov 2025 22:54:04 -0500
Received: from mail-oa1-x41.google.com ([2001:4860:4864:20::41]:43191)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vO6bO-00065I-6S
 for 79877 <at> debbugs.gnu.org; Tue, 25 Nov 2025 22:54:01 -0500
Received: by mail-oa1-x41.google.com with SMTP id
 586e51a60fabf-3d47192e99bso584407fac.0
 for <79877 <at> debbugs.gnu.org>; Tue, 25 Nov 2025 19:53:58 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1764129232; x=1764734032; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=YDc4pd/tcIR5Q72kwDZynjHAua/DLjPcrnxXrbe3cXM=;
 b=bC7mO8ZZbiQ4q822DDR4Mv0s/lH6xni6fhwnLcMx3uH78KVuyvc9spRk8KreLxnT6B
 mtE+FuCiWDFgDSTfBsvRpIiEKwaHN9CHYx90pdEjOO+tmH3RSg6y+JuJnyGVr19jjD9L
 nKHBBfKdqoc8+D9Tb0xHX1L1uLIpCk1ImOF3Wh5h3sZyIaSw2qp2YvmJohA5gw5yDgZe
 lWkkzv0psAT5ZnbTVTbCJCBKAPI5deOftFVl5s6x7FVfHEp5Jhh09uOJyUL1BfISs1QH
 LxXrxg9SkGYRuNQmEoBDLVmdBsH3QQubVBgIQ7Y+BcWDpIcM28RwFL2yUgzPu5YMJvoi
 hxSA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1764129232; x=1764734032;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=YDc4pd/tcIR5Q72kwDZynjHAua/DLjPcrnxXrbe3cXM=;
 b=jgUkJlrCXOk6kOORAPjt8sBfwqQjGYQQ+y9bnQ0COqR3Fv7PWXiMpkxP0eUK3bJbsg
 lQVuVAm8w6v52tniebmu9I5roNjkzXkC9ph1UmqednuHHXyGXWgT7ZRS5KSADYMV6tw1
 8EK7LuTwGz4EHDoksuQ2weda+BwPaUEqFm0NQYRU82D8oVzT3wFC6fkJb6wkAXWbsrKD
 rFlke6aFrBBfCLGyx4rP4nVEsHfO6ZFf+uS5gLxgS7DjWOULdbRymwKVPx9TzaC9PtkU
 FMNeafdy9RfOkRXghza01pufqzp/IhNYEoNZjBvAnMVeaa6VbNpBbb2gnsJMT5AafB7v
 lHiQ==
X-Gm-Message-State: AOJu0Yx5qxc++pI3pDZThgi6Gwna2EhHCVRYZ2ukeErFpiz06uh4Iq7P
 EGw9Xdro7L8gH+Bt8BKNhibQ5VYtvAaAk1CAA+l04vq5a4vUKGYI/gGy1AjyVcoD
X-Gm-Gg: ASbGncsNngjMi6g3TdKKWDjejnAcm0EHnGTl+AisCNhTW4Z+8nEat0YfO2BVqPOChA1
 zRtL0hZJTPqV4TUs/3PXBIdninxNGkC/OAkQyVLk+c2UBMA2BNqDatDJ4tHjK4NNeGquamUCrvw
 Ei5C/K6EBis4eMIkm1bfKqRT9xOmBfZGDfmdYK2WG0z/uerNL3UNUoCMEsxL75M+7W3VqGRHFZg
 Pp8gLdrpuPxLZfQf8jOjuLLgqzYtvRkUzfypsRg6UoKuzibk5gu4lmufBEaUTEX1Jqsya/YXA90
 hckylTWi8PLkN2GM7+gDm3yeMK8ZX/x83MdXsAbbUYwk3GYycAX5s2uPNdFe3x603pm1pZUqIMa
 Q/GarGtBt1B9ZGGJX4lQez1VufSPnFymID4ojHaASfAKG+xUOIb+eVqkFAphFAtM8Eg/Pyjnxhp
 Pw19JY
X-Google-Smtp-Source: AGHT+IFi/imEOkPNLsNIRfS8mHmg8hdObWSXjuYbzLASD4Pk2NkvkC6MxAWkfMk5L2xDFHvHlbr38g==
X-Received: by 2002:a05:6871:4d3:b0:3e8:824c:a0be with SMTP id
 586e51a60fabf-3ecbbe847dcmr8285451fac.26.1764129231910; 
 Tue, 25 Nov 2025 19:53:51 -0800 (PST)
Received: from fedora ([189.215.160.233]) by smtp.gmail.com with ESMTPSA id
 586e51a60fabf-3ec9c2c9bdesm8442922fac.4.2025.11.25.19.53.51
 for <79877 <at> debbugs.gnu.org>
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Tue, 25 Nov 2025 19:53:51 -0800 (PST)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: 79877 <at> debbugs.gnu.org
Subject: Re: bug#79877: [PATCH] hideshow.el: New commands 'hs-cycle' and
 'hs-toggle-all'
In-Reply-To: <87pl9a3lzr.fsf@HIDDEN>
References: <87pl9a3lzr.fsf@HIDDEN>
Date: Tue, 25 Nov 2025 21:53:49 -0600
Message-ID: <871pll1mb6.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: 79877
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 (/)

I realized that this doesn't actually work quite right, so I re-read the
`outline-cycle` code, and it seems better to replicate its functionality
instead.

-- 
- E.G via Gnus and Org.




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

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


Received: (at submit) by debbugs.gnu.org; 25 Nov 2025 20:16:59 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Nov 25 15:16:59 2025
Received: from localhost ([127.0.0.1]:55361 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1vNzT8-0005Cs-Am
	for submit <at> debbugs.gnu.org; Tue, 25 Nov 2025 15:16:58 -0500
Received: from lists.gnu.org ([2001:470:142::17]:36058)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <eg642616@HIDDEN>)
 id 1vMcFS-0001yz-L2
 for submit <at> debbugs.gnu.org; Fri, 21 Nov 2025 20:17:25 -0500
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 1vMcFG-0000xk-GG
 for bug-gnu-emacs@HIDDEN; Fri, 21 Nov 2025 20:17:00 -0500
Received: from mail-oa1-x41.google.com ([2001:4860:4864:20::41])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <eg642616@HIDDEN>)
 id 1vMcF6-00060W-2l
 for bug-gnu-emacs@HIDDEN; Fri, 21 Nov 2025 20:16:55 -0500
Received: by mail-oa1-x41.google.com with SMTP id
 586e51a60fabf-3e80c483a13so1668944fac.2
 for <bug-gnu-emacs@HIDDEN>; Fri, 21 Nov 2025 17:16:33 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1763774188; x=1764378988; darn=gnu.org;
 h=mime-version:message-id:date:subject:to:from:from:to:cc:subject
 :date:message-id:reply-to;
 bh=h6GwvuQL04GG733fecVbAvgEZRYz4pfBb5NNchXOFyE=;
 b=ABhAHtcWoRSk5x4M8BvO8NgKjql+ozly7Y/WDTp44McfcpYUbvc+EYP+gRDuRhSeJW
 nGKPr5SdlYsuhiWShXEpm0jN9wsEBzguMDkSu7Pm8FyE9sPPQB/prXfp9jnFnPE6oC9U
 7h1kttUhCtiXpR/uYSTeuurdk8K5HLZ7CjkhYFewBJt9XkdrqayJAHDD2UhDzC6c752Y
 kyN/oxwbDiM+kU+pTOf0zCtBMg+UDX6Nf6alBQgz33wSLcL2se9oTuxmnfM9hKB095e8
 +Mlpcdm/1pnNgbdEDfSZ4iD5rGYFrFKlRUz6p4Gz0+/8gMDRi9cpHSTDT/PTgqlGaDN8
 WW2w==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1763774188; x=1764378988;
 h=mime-version:message-id:date:subject:to:from:x-gm-gg
 :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
 bh=h6GwvuQL04GG733fecVbAvgEZRYz4pfBb5NNchXOFyE=;
 b=vjhh3eRxa0IfOGvaLIiWvAfTXpA8J8p3Z+Bx72eMPujdPOV2YLLV4XgefMokcinHk1
 dNQ5V6XKq0RnUmjY6Vc6cr3RHsa789G3mWPuuxJiyLr+Tj585/OEKqXGfWtwOmkzi78K
 c7UsAz0MO9cQyW+7dXO9eSKoF6aWnH0d2+YrIdGe5FOx2A/WvDx4qebs6NaMLQDAK0po
 jKiprj2foFYUEUVnrUeWEFHEXkyPsHrxmYMY5hEfqd/MlUst80Xj4nmb8NX0UqoeUyKe
 l2/9SPP0Y7Y9TQJG+1JAWPbaDxIOfeIl96DZU2IqBa67vI0mZ868u+LE41fX0A/4cWGK
 dGjA==
X-Gm-Message-State: AOJu0YxV7yxbByIMRrQLoB8KrTpDqNavBxqUUbOtqVJUKAhlbprf1PvD
 7TFXsDYBLMf946ciO+CIRv0Sem/DBaA9RP9QYhTSZUdqy9+HrZ+r6wEMrJ0drrVR
X-Gm-Gg: ASbGnct9IvGBwFT6CseH3Oayq/3/vMVpxqcLwtJw6L2zG5y4rBG9Dp6rqKUE+XxXf3I
 QE2064MfjGlSw0t2IP1oCu8NM0ybELKlvko4gqxvPXVRoLv0RUlm4kwFobEVOwoTONvovJga7IS
 By7EkAVD8NQMhOmwLyMS+bhMZAIDHDKeKQkpUy0ncCa9Iptd11Cuo6YgkmCDtYbRnM+hfaCu7H1
 2LvfavQQSGLVQQ49iR1rOBRaTzi5zX9IELCMx+zb5yAP2XGbq6TzXJu2Ri1qriFslEpQI8qA3pM
 7GkWMX9yc7Y8vs3QF8bQ5Cl1AquM1HRD/GkBJdjHAjW+1y/QJVq43v2unfdmRAvzU8U9SrtUFl0
 GBGihICyQohfJiQf0CA3TK4axtYWWmtW5BkPpYwaYmtZdD0hqKY5RsJNCT3vJYX6n5obMUlQQz8
 3OvfbaOBXVl8HeHzo=
X-Google-Smtp-Source: AGHT+IFa0hQ/dfPGoAmk3pYlCGYWF5CwzQ2kFltatsX0CdaO6F9/2ZTLlt/qTPk39OM/dTP/vnc7zw==
X-Received: by 2002:a05:6808:18a2:b0:441:c8a2:ba1b with SMTP id
 5614622812f47-45115aa5f54mr1523081b6e.40.1763774187964; 
 Fri, 21 Nov 2025 17:16:27 -0800 (PST)
Received: from fedora ([189.215.160.233]) by smtp.gmail.com with ESMTPSA id
 5614622812f47-450ffe2d3d1sm2184156b6e.3.2025.11.21.17.16.26
 for <bug-gnu-emacs@HIDDEN>
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Fri, 21 Nov 2025 17:16:27 -0800 (PST)
From: =?utf-8?Q?Elijah_Gabe_P=C3=A9rez?= <eg642616@HIDDEN>
To: bug-gnu-emacs@HIDDEN
Subject: [PATCH] hideshow.el: New commands 'hs-cycle' and 'hs-toggle-all'
X-Debbugs-Cc: Thien-Thi Nguyen <ttn@HIDDEN>, Dan Nicolaescu <dann@HIDDEN>
Date: Fri, 21 Nov 2025 19:16:24 -0600
Message-ID: <87pl9a3lzr.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
Received-SPF: pass client-ip=2001:4860:4864:20::41;
 envelope-from=eg642616@HIDDEN; helo=mail-oa1-x41.google.com
X-Spam-Score: 0.3 (/)
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

Tags: patch

This patch adds 2 new commands, hs-cycle (as counterpart to
oultine-cycle/org-cycle) and hs-toggle-all.

hs-cycle implements a folding similar to outline/org, cycling the block
visibility: hide the block first, show the block but hide first children
blocks, and show the whole block.

The 2 commands were extracted (in part) from 2 existing ones made by
Karthinks, who gave me permission to use them (Thank you).

However, unlike how outline-cycle implements it, this parses the block
looking for how many hidden and non-hidden blocks there are, avoiding
creating more overlays in the buffer.

Currently both commands are bound to "C-TAB" and "C-S-TAB" (also based
on the Karthinks code)

Thanks.


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-hideshow.el-New-commands-hs-cycle-and-hs-toggle-all.patch

From 11a4b306d9ebc376b96c59682ec97df844336ae3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <eg642616@HIDDEN>
Date: Thu, 18 Sep 2025 19:24:53 -0600
Subject: [PATCH] hideshow.el: New commands 'hs-cycle' and 'hs-toggle-all'

* lisp/progmodes/hideshow.el (hs-prefix-map): Add the new
commands to the keymap.
(hs-hide-level-recursive): Simplify.
(hs--count-recursive-blocks): New function.
(hs--toggle-all-state): New internal variable.
(hs-cycle, hs-toggle-all): New commands.

Co-authored-by: Karthik Chikmagalur <karthikchikmagalur@HIDDEN>
---
 lisp/progmodes/hideshow.el | 112 +++++++++++++++++++++++++++++--------
 1 file changed, 88 insertions(+), 24 deletions(-)

diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index 9474332e269..78852fc2342 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -504,16 +504,18 @@ hs-prefix-map
   :doc "Keymap for hideshow commands."
   :prefix t
   ;; These bindings roughly imitate those used by Outline mode.
-  "C-h"   #'hs-hide-block
-  "C-s"   #'hs-show-block
-  "C-M-h" #'hs-hide-all
-  "C-M-s" #'hs-show-all
-  "C-l"   #'hs-hide-level
-  "C-c"   #'hs-toggle-hiding
-  "C-a"   #'hs-show-all
-  "C-t"   #'hs-hide-all
-  "C-d"   #'hs-hide-block
-  "C-e"   #'hs-toggle-hiding)
+  "C-h"     #'hs-hide-block
+  "C-d"     #'hs-hide-block
+  "C-s"     #'hs-show-block
+  "C-M-h"   #'hs-hide-all
+  "C-t"     #'hs-hide-all
+  "C-M-s"   #'hs-show-all
+  "C-a"     #'hs-show-all
+  "C-l"     #'hs-hide-level
+  "C-c"     #'hs-toggle-hiding
+  "C-e"     #'hs-toggle-hiding
+  "C-TAB"   #'hs-cycle
+  "C-S-TAB" #'hs-toggle-all)
 
 (defvar-keymap hs-minor-mode-map
   :doc "Keymap for hideshow minor mode."
@@ -1184,25 +1186,31 @@ hs-find-next-block
   (and (< (point) maxp)
        (re-search-forward regexp maxp t)))
 
-(defun hs-hide-level-recursive (arg minp maxp)
-  "Recursively hide blocks ARG levels below point in region (MINP MAXP)."
+(defun hs-hide-level-recursive (arg &optional minp maxp)
+  "Recursively hide blocks ARG levels below point in region (MINP MAXP).
+If MINP and MAXP are not specified, it will search for a near block and
+use its position instead."
+  ;; If we are near of a block, set MINP and MAXP according to that
+  ;; block positions.
   (when (funcall hs-find-block-beginning-function)
-    (setq minp (1+ (point)))
-    (funcall hs-forward-sexp-function 1)
-    (setq maxp (1- (point))))
+    (let ((block (hs-block-positions)))
+      (setq minp (1+ (car block)) maxp (1- (cadr block)))))
+
+  ;; Show all blocks in that region
   (unless hs-allow-nesting
     (hs-discard-overlays minp maxp))
+
   (goto-char minp)
+
   (while (funcall hs-find-next-block-function hs-block-start-regexp maxp nil)
-    (when (save-match-data
-	    (not (nth 8 (syntax-ppss)))) ; not inside comments or strings
-      (if (> arg 1)
-	  (hs-hide-level-recursive (1- arg) minp maxp)
-        ;; `hs-hide-block-at-point' already moves the cursor, but if it
-        ;; fails, return to the previous position where we were.
-	(unless (and (goto-char (match-beginning hs-block-start-mdata-select))
-	             (hs-hide-block-at-point t))
-            (goto-char (match-end hs-block-start-mdata-select))))))
+    (if (> arg 1)
+	(hs-hide-level-recursive (1- arg))
+      ;; `hs-hide-block-at-point' already moves the cursor, but if it
+      ;; fails, return to the previous position where we were.
+      (unless (and (goto-char (match-beginning hs-block-start-mdata-select))
+	           (hs-hide-block-at-point t))
+        (goto-char (match-end hs-block-start-mdata-select)))))
+
   (goto-char maxp))
 
 (defmacro hs-life-goes-on (&rest body)
@@ -1442,6 +1450,62 @@ hs-hide-initial-comment-block
          (when (hs-hideable-region-p beg end)
            (hs-hide-comment-region beg end)))))))
 
+(defun hs--count-recursive-blocks ()
+  "Return a list containing the amount of block and hidden blocks."
+  (save-excursion
+    (let ((maxp (save-excursion
+                  (goto-char (cadr (hs-block-positions)))
+                  (pos-eol)))
+          (blocks 0) (hidden 0))
+      (while (not (>= (pos-eol) maxp))
+        (save-excursion
+          (while (funcall hs-find-next-block-function hs-block-start-regexp (pos-eol) nil)
+            (save-excursion
+              (goto-char (match-beginning 0))
+              (when (hs-hideable-region-p)
+                (incf blocks)
+                (when (hs-already-hidden-p) (incf hidden))))))
+        (forward-line))
+      (list blocks hidden))))
+
+(defun hs-cycle (&optional level)
+  "Cycle the visibility state of the current block.
+With argument, hide only the LEVEL levels below point"
+  (interactive "p")
+  (hs-life-goes-on
+   (when (or (funcall hs-looking-at-block-start-predicate)
+             (and (goto-char (line-beginning-position))
+                  (funcall hs-find-block-beginning-function)))
+     (let* (hs-allow-nesting
+            (blocks (hs--count-recursive-blocks))
+            (counter (car blocks))
+            (hidden (cadr blocks)))
+       (cond
+        ;; If block has no child blocks, just toggle the visibility.
+        ((= counter 1) (hs-toggle-hiding))
+        ;; Hide n levels if LEVEL is specified.
+        ((> level 1) (hs-hide-level-recursive level))
+        ;; If all the child blocks (including the parent) are hidden,
+        ;; only hide the first levels.
+        ((= hidden counter) (hs-hide-level-recursive 1))
+        ;; If only a few are not hidden, then show the whole block.
+        ((and (< hidden counter) (not (zerop hidden)))
+         (hs-show-block))
+        ;; If the parent and child blocks the is not hidden, then hide
+        ;; the whole block.
+        ((not (hs-already-hidden-p)) (hs-hide-block)))))))
+
+(defvar-local hs--toggle-all-state)
+
+(defun hs-toggle-all ()
+  "Toggle the visibility of all the blocks in the current buffer."
+  (interactive)
+  (if hs--toggle-all-state
+      (let (hs-allow-nesting)
+        (hs-discard-overlays (point-min) (point-max)))
+    (hs-hide-all))
+  (setq-local hs--toggle-all-state (not hs--toggle-all-state)))
+
 ;;;###autoload
 (define-minor-mode hs-minor-mode
   "Minor mode to selectively hide/show code and comment blocks.
-- 
2.51.1


--=-=-=
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 ttn@HIDDEN, dann@HIDDEN, bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to ttn@HIDDEN, dann@HIDDEN, bug-gnu-emacs@HIDDEN:
bug#79877; 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: Mon, 1 Dec 2025 18:00:03 UTC

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