Subject: Re: bug#24221: 25.1.50; binding anonymous functions to keys cause help buffer navigation errors

From: [email-masked]
Date: Mon, 03 Oct 2016 19:33:50 -0400

tags 24221 patch
quit

Drew Adams <[email-masked]> writes:
>
> 2. Someone changed `describe-function' so that it now barfs
>    if its arg is not a function symbol.

Yes, seems to have been 82d0f42a "* lisp/help-fns.el
(describe-function): More type checking[...]".  I think it was an
accident: the non-interactive case wasn't considered, probably because
the docstring doesn't mention it.

Here's a patch that moves the checks into the interactive form and
updates the docstring:

>From 7dffe1868222f33c8845cac7b5e46836149c72f8 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <[email-masked]>
Date: Mon, 3 Oct 2016 18:49:56 -0400
Subject: [PATCH v1] Let describe-function work for lambda again

Since commit "* lisp/help-fns.el (describe-function): More type
checking[...]", `describe-function' throws a user-error when given a
non-symbol.  This prevents the [back] button in a *Help* buffer from
working when the page it goes back to describes an anonymous
function (e.g., the result of `describe-key' on a key which is bound to
a lambda form).

* lisp/help-fns.el (describe-function): Move the checks on FUNCTION
being an fbound symbol into the `interactive' form.  This allows
non-interactive calls to pass an anonymous function (Bug #24221).  Note
that passing a non-bound symbol non-interactively will still trigger a
`void-function' error from `describe-function-1'.
---
 lisp/help-fns.el | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 26d8839..7dfa670 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -50,23 +50,24 @@ describe-function-orig-buffer
 
 ;;;###autoload
 (defun describe-function (function)
-  "Display the full documentation of FUNCTION (a symbol)."
+  "Display the full documentation of FUNCTION (a symbol).
+When called from lisp, FUNCTION may also be a function object."
   (interactive
-   (let ((fn (function-called-at-point))
-	 (enable-recursive-minibuffers t)
-	 val)
-     (setq val (completing-read (if fn
-				    (format "Describe function (default %s): " fn)
-				  "Describe function: ")
-				obarray 'fboundp t nil nil
-				(and fn (symbol-name fn))))
-     (list (if (equal val "")
-	       fn (intern val)))))
-  (or (and function (symbolp function))
-      (user-error "You didn't specify a function symbol"))
-  (or (fboundp function)
-      (user-error "Symbol's function definition is void: %s" function))
-
+   (let* ((fn (function-called-at-point))
+          (enable-recursive-minibuffers t)
+          (val (completing-read
+                (if fn
+                    (format "Describe function (default %s): " fn)
+                  "Describe function: ")
+                obarray 'fboundp t nil nil
+                (and fn (symbol-name fn)))))
+     (unless (equal val "")
+       (setq fn (intern val)))
+     (unless (and fn (symbolp fn))
+       (user-error "You didn't specify a function symbol"))
+     (unless (fboundp fn)
+       (user-error "Symbol's function definition is void: %s" fn))
+     (list fn)))
   ;; We save describe-function-orig-buffer on the help xref stack, so
   ;; it is restored by the back/forward buttons.  'help-buffer'
   ;; expects (current-buffer) to be a help buffer when processing
-- 
2.9.3