Wilfred / helpful

A better Emacs *help* buffer
1.11k stars 62 forks source link

Stack overflow in helpful--tree-any-p #279

Closed minad closed 2 years ago

minad commented 2 years ago

The issue occurs when opening the helpful buffer on certain large macro-generated functions, for example the command cape-tex from my Cape package.

Debugger entered--Lisp error: (error "Lisp nesting exceeds ‘max-lisp-eval-depth’")
  helpful--tree-any-p(#f(compiled-function (sexp) #<bytecode 0x1685b26de7f5>) "\\female")
  helpful--tree-any-p(#f(compiled-function (sexp) #<bytecode 0x1685b26de7f5>) ("\\female" . 9792))
  ...
  helpful--tree-any-p(#f(compiled-function (sexp) #<bytecode 0x1685b26de7f5>) (progn (defvar cape--tex-list '(("\\" . 160) ("\\\"" . 776) ("\\\"'" . 8220) ("\\\"<" . 171) ("\\\">" . 187) ("\\\"A" . 196) ("\\\"E" . 203) ("\\\"H" . 7718) ("\\\"I" . 207) ("\\\"O" . 214) ("\\\"U" . 220) ("\\\"W" . 7812) ("\\\"X" . 7820) ("\\\"Y" . 376) ("\\\"\\'I" . 7726) ("\\\"\\'U" . 471) ("\\\"\\'i" . 7727) ("\\\"\\'u" . 472) ("\\\"\\'{I}" . 7726) ("\\\"\\'{U}" . 471) ("\\\"\\'{i}" . 7727) ("\\\"\\'{u}" . 472) ("\\\"\\=A" . 478) ("\\\"\\=O" . 554) ("\\\"\\=U" . 469) ("\\\"\\=a" . 479) ("\\\"\\=o" . 555) ("\\\"\\=u" . 470) ("\\\"\\={A}" . 478) ("\\\"\\={O}" . 554) ("\\\"\\={U}" . 469) ("\\\"\\={a}" . 479) ("\\\"\\={o}" . 555) ("\\\"\\={u}" . 470) ("\\\"\\`U" . 475) ("\\\"\\`u" . 476) ("\\\"\\`{U}" . 475) ("\\\"\\`{u}" . 476) ("\\\"\\vU" . 473) ("\\\"\\vu" . 474) ("\\\"\\v{U}" . 473) ("\\\"\\v{u}" . 474) ("\\\"`" . 8222) ("\\\"a" . 228) ("\\\"e" . 235) ("\\\"h" . 7719) ("\\\"i" . 239) ("\\\"o" . 246) ("\\\"t" . 7831) ("\\\"u" . 252) ...)) (defalias 'cape--tex-annotation #'(lambda (name) (let* ((char ...)) (if char (format " %c" char) nil)))) (defalias 'cape--tex-docsig #'(lambda (name) (let* ((charl ...)) (if charl (format "%s (%s)" ... ...) nil)))) (defalias 'cape--tex-exit #'(lambda (name status) (if (eq status 'exact) nil (let* (...) (if char ... nil))))) (defvar cape--tex-properties (list :annotation-function #'cape--tex-annotation :company-docsig #'cape--tex-docsig :exit-function #'cape--tex-exit :company-kind #'(lambda (_) 'text)) "Completion extra properties for `tex'.") (defalias 'cape-tex #'(lambda (&optional interactive) "Complete unicode character at point.\nUses the same..." (interactive (list t)) (if interactive (let (completion-cycle-threshold) (cape--interactive ...)) (require 'thingatpt) (let (...) (append ... cape--tex-properties)))))))
  helpful--find-by-macroexpanding(#<buffer cape-0.3/cape.el> cape-sgml t)
  helpful--definition(cape-sgml t)
  helpful-update()
  helpful-callable(cape-sgml)
  funcall-interactively(helpful-callable cape-sgml)
  call-interactively(helpful-callable nil nil)
  command-execute(helpful-callable)

I could change the way I generate the code. However I have not observed problems so far except with helpful-callable.

Wilfred commented 2 years ago

Thanks, this should now work. Let me know if not.

minad commented 2 years ago

Thanks! I will check it. The downside of your implementation is that it results in many allocations. Ideally you could use limited recursion and only switch to the manual stack if a certain depth is exceeded.

EDIT: Works well! Thanks again!