helpful

a fork of Wilfred's helpful
git clone https://git.trogloxene.org/helpful.git
Log | Files | Refs | README

commit 217b38398bfa523c48f630b06b21427974d93e1d
parent 8df39c15d290cd499ef261de868191d3fc84f75a
Author: Wilfred Hughes <me@wilfred.me.uk>
Date:   Fri, 10 Dec 2021 21:38:58 -0800

Rewrite helpful--tree-any-p as a loop

Fixes #279

Diffstat:
MCHANGELOG.md | 2++
Mhelpful.el | 18+++++++++++-------
Mtest/helpful-unit-test.el | 4++++
3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -8,6 +8,8 @@ Fixed issue with displaying circular data structures. Fixed a crash in `helpful-variable` in files that weren't syntactically valid lisp. +Fixed stack overflow in macroexpanding large s-expressions (#279). + # v0.18 Show the original value for custom variables whose value has changed. diff --git a/helpful.el b/helpful.el @@ -1317,13 +1317,17 @@ If it fails, attempt to partially macroexpand FORM." (defun helpful--tree-any-p (pred tree) "Walk TREE, applying PRED to every subtree. Return t if PRED ever returns t." - (cond - ((null tree) nil) - ((funcall pred tree) t) - ((not (consp tree)) nil) - (t (or - (helpful--tree-any-p pred (car tree)) - (helpful--tree-any-p pred (cdr tree)))))) + (catch 'found + (let ((stack (list tree))) + (while stack + (let ((next (pop stack))) + (cond + ((funcall pred next) + (throw 'found t)) + ((consp next) + (push (car next) stack) + (push (cdr next) stack)))))) + nil)) (defun helpful--find-by-macroexpanding (buf sym callable-p) "Search BUF for the definition of SYM by macroexpanding diff --git a/test/helpful-unit-test.el b/test/helpful-unit-test.el @@ -1072,3 +1072,7 @@ find the source code." "Ensure that we can describe an autoloaded function that has advice attached before it is loadedl." (helpful-function 'ruby-mode)) + +(ert-deftest helpful--tree-any-p () + (should (helpful--tree-any-p (lambda (x) (eq x 1)) '((((1)))))) + (should (helpful--tree-any-p (lambda (x) (eq x 1)) (cons 2 1))))