From aa17e562b9844a50b8b01777c83830d3c4ead963 Mon Sep 17 00:00:00 2001 From: Morgan Willcock 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