Subject: bug#77510: 31.0.50; help-customize fails with multiply defined symbols

From: Stephen Berman <[email-masked]>
Date: Sun, 13 Apr 2025 10:59:05 +0200

On Sun, 13 Apr 2025 03:44:49 +0300 Dmitry Gutov <[email-masked]> wrote:

> Hi! Thanks for reporting.
>
> On 04/04/2025 01:16, Stephen Berman via Bug reports for GNU Emacs, the
> Swiss army knife of text editors wrote:
>> 0. emacs -Q
>> 1. Type `C-h o fringe-mode RET' to pop up a *Help* buffer displaying
>>     help for both the function fringe-mode and the variable fringe-mode.
>> 2. In the *Help* buffer type `c'.
>> => Emacs dings and displays the message "No variable or face to customize"
>>
>> When executing this recipe in emacs-30, after step 2 Emacs switches to a
>> *Customize* buffer for the variable fringe-mode, which is the expected
>> behavior after typing `c' (help-customize) in *Help*.  This is broken in
>> master.  The breakage is due to this commit:
>>
>> commit e776df2a3eae0454ea85287e15ebba649bf8e918
>> Author:     Dmitry Gutov <[email-masked]>
>> Commit:     Dmitry Gutov <[email-masked]>
>> CommitDate: Sun Oct 6 04:32:00 2024 +0300
>>
>>      help-setup-xref: Keep the local values only of some variables
>>
>>      * lisp/help-mode.el (help-setup-xref): Kill all local variables,
>>      saving ones that are known to need to be preserved (bug#73637).
>>
>> and the breakage remained after the two followup commits, which is the
>> current code state.
>>
>> According to my debugging, calling help-setup-xref at the end of
>> describe-symbol after the function definition help has been added to the
>> *Help* buffer nullifies the property list of help-mode--current-data
>> (this happens on evaluating `(funcall major-mode)' in help-setup-xref
>> when the value of major-mode is 'help-mode), which renders
>> help-customize a noop.  The following patch fixes the breakage according
>> to my brief testing, though I'm not sure it doesn't have unwanted
>> side-effects (but at least I get the same test results on running make
>> check with the patch as without it).
>
> It seems like your proposal would regress the bug report that's
> referenced in the above commit message. The change has the goal to reset
> some buffer-local variables, and the current means to do that is to call
> the major mode function again.
>
> If the major-mode function is not called, the vars are not reset.
>
> What are the other options we could use?
>
> help-setup-xref's docstring says it should be called very early -
> perhaps before the value of help-mode--current-data is assigned?
>
> Making help-mode--current-data would also be an option, but it won't
> work alone because help-mode function sets it to nil explicitly as well.
> I wonder what will happen if we remove that assignment.
>
> Finally, if 'describe-symbol' is the only main exception (where
> help-setup-xref is called late), we could save and restore the current
> value of help-mode--current-data just there.
>
> Like this:
>
> diff --git a/lisp/help-fns.el b/lisp/help-fns.el
> index 6c4c3f4da97..fa7241d3e9d 100644
> --- a/lisp/help-fns.el
> +++ b/lisp/help-fns.el
> @@ -1965,7 +1965,8 @@ describe-symbol
>           (unless single
>             ;; Don't record the `describe-variable' item in the stack.
>             (setq help-xref-stack-item nil)
> -          (help-setup-xref (list #'describe-symbol symbol) nil))
> +          (let ((help-mode--current-data help-mode--current-data))
> +            (help-setup-xref (list #'describe-symbol symbol) nil)))
>           (goto-char (point-max))
>           (help-xref--navigation-buttons)
>           (goto-char (point-min))))))

I confirm this fixes the issue I reported, so if my patch is
problematical, I'm fine with yours.  Thanks!

Steve Berman