Subject: Re: bug#73533: [PATCH] Rewrite speedbar expansion for all descendants

From: Morgan Willcock <[email-masked]>
Date: Mon, 30 Sep 2024 10:03:18 +0100

Morgan Willcock <[email-masked]> writes:

> The old code with the fix for bug#35014 narrowed each item recursively
> with the narrowing around the top level preventing a top-level sibling
> being reached.

The change that was made in bug#35014 looks like it broke the expansion
when the item was already partially expanded, so attached is a modified
version of the patch that completely removes the narrowing-per-item
approach and also includes more comments.

Thanks,
Morgan

-- 
Morgan Willcock
>From aa17e562b9844a50b8b01777c83830d3c4ead963 Mon Sep 17 00:00:00 2001
From: Morgan Willcock <[email-masked]>
Date: Sat, 28 Sep 2024 19:11:11 +0100
Subject: [PATCH] Rewrite speedbar expansion for all descendants

Rewrite 'speedbar-expand-line-descendants' to avoid getting into
an infinite loop by reaching max-lisp-eval-depth.  The new
method avoids querying and displaying information for every
movement, instead using a single message to indicate that
expansion is in progress, and so is significantly faster.  The
narrowing per item introduced by the fix for bug#35014 is
removed because it prevented expanded descendant items when the
top-level item was already expanded.

* lisp/speedbar.el (speedbar-expand-line-descendants): Use
simpler line motion and no recursion.  Output messages
indicating when expansion is in progress and when it is
completed.  Fix expansion of descendants where the top-level
item was already expanded.
---
 lisp/speedbar.el | 45 ++++++++++++++++++++++++++++++---------------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index c13c977938b..723a5595854 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -3172,21 +3172,36 @@ speedbar-expand-line-descendants
   "Expand the line under the cursor and all descendants.
 Optional argument ARG indicates that any cache should be flushed."
   (interactive "P")
-  (save-restriction
-    (narrow-to-region (line-beginning-position)
-                      (line-beginning-position 2))
-    (speedbar-expand-line arg)
-    ;; Now, inside the area expanded here, expand all subnodes of
-    ;; the same descendant type.
-    (save-excursion
-      (speedbar-next 1) ;; Move into the list.
-      (let ((err nil))
-        (while (not err)
-	  (condition-case nil
-	      (progn
-	        (speedbar-expand-line-descendants arg)
-	        (speedbar-restricted-next 1))
-	    (error (setq err t))))))))
+  (dframe-message "Expanding all descendants...")
+  (save-excursion
+    (with-restriction
+        ;; Narrow around the top-level item to ensure that later sibling
+        ;; items will not be entered.
+        (line-beginning-position)
+        (condition-case nil
+            (save-excursion
+              (speedbar-restricted-move 1)
+              ;; Use the line beginning position of the next sibling
+              ;; item to apply the restriction.
+              (line-beginning-position))
+          ;; This was the last sibling item so just apply the
+          ;; restriction to the end of the buffer.  This fixes the
+          ;; change applied in bug#35014 which prevented the top-level
+          ;; item from having its descendants expanded if it was already
+          ;; expanded.
+          (error (point-max)))
+      ;; Expand every line until the end of the restriction is reached.
+      (while (zerop (progn
+                      ;; Assume that the line will expand and try to
+                      ;; expand it.
+                      (speedbar-expand-line arg)
+                      ;; Moving forwards will be moving into the
+                      ;; expanded lists if one opened, into an already
+                      ;; expanded list if it was already open, to a
+                      ;; sibling, or to the end of restriction.
+                      (forward-line 1))))))
+  (dframe-message "Expanding all descendants...done")
+  (speedbar-position-cursor-on-line))
 
 (defun speedbar-contract-line-descendants ()
   "Expand the line under the cursor and all descendants."
-- 
2.39.5