]> git.eshelyaron.com Git - emacs.git/commitdiff
Rewrite Speedbar expansion for all descendants (bug#73533)
authorMorgan Willcock <morgan@ice9.digital>
Sat, 5 Oct 2024 17:33:51 +0000 (18:33 +0100)
committerEshel Yaron <me@eshelyaron.com>
Tue, 22 Oct 2024 18:55:17 +0000 (20:55 +0200)
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--get-line-indent-level): New
function to return the indentation level of the current line.
(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.

(cherry picked from commit bcc4e64fa7aab9f44e3a7bcdf651a32ec52866c2)

lisp/speedbar.el

index f84b4475ba13ca8d98f035a3ea2a6df26c63b879..df7212866a1234693e36b5acf74c1286a6c90504 100644 (file)
@@ -3144,25 +3144,32 @@ With universal argument ARG, flush cached data."
        (speedbar-do-function-pointer))
     (error (speedbar-position-cursor-on-line))))
 
+(defun speedbar--get-line-indent-level ()
+  "Return the indentation level of the current line."
+  (save-excursion
+    (beginning-of-line)
+    (if (looking-at "[0-9]+:")
+        (string-to-number (match-string 0))
+      0)))
+
 (defun speedbar-expand-line-descendants (&optional arg)
   "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
+    (let ((top-depth (speedbar--get-line-indent-level)))
+      ;; Attempt to expand the top-level item.
+      (speedbar-expand-line arg)
+      ;; Move forwards, either into the newly expanded list, onto an
+      ;; already expanded list, onto a sibling item, or to the end of
+      ;; the buffer.
+      (while (and (zerop (forward-line 1))
+                  (not (eobp))
+                  (> (speedbar--get-line-indent-level) top-depth)
+                  (speedbar-expand-line arg)))))
+  (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."