Subject: bug#77118: 31.0.50; help-key-binding face in help buffer

From: Stefan Kangas <[email-masked]>
Date: Wed, 19 Mar 2025 12:15:40 -0700

Eli Zaretskii <[email-masked]> writes:

>> From: Arash Esbati <[email-masked]>
>> Date: Wed, 19 Mar 2025 14:05:21 +0100
>>
>> when I eval the following code:
>>
>> --8<---------------cut here---------------start------------->8---
>> (let ((help-form (substitute-command-keys "\
>> Select with a key:
>> \\`h'   do this,
>> \\`k'   do that,
>> \\`RET' do nothing.")))
>>   (read-char-choice (substitute-command-keys
>>                      (format "\
>> This (\\`h'), That (\\`k'), Nothing (\\`RET'), Help (\\`%s'): "
>>                              (key-description (vector help-char))))
>>                     '(?h ?k ?\r)))
>> --8<---------------cut here---------------end--------------->8---
>>
>> and do 'C-h', h, k and RET don't receive the help-key-binding face in
>> the help buffer which pops up.  What I see with 'emacs -Q' is attached.
>> Note the difference in the minibuffer.
>>
>> The reason seems to be in the implementation of `help-form-show' using
>> `princ' which strips properties.  If this is intentional, it doesn't
>> match definitions of `help-form' in Emacs tree.  Take for example
>> dired-aux.el which pushes the string for `help-form' also through
>> `substitute-command-keys'[1,2,3].
>>
>> In case this report is confirmed, a possible solution is provided
>> here[4].
>
> Stefan, any comments or reasons why we use princ there?

There is no deep reason.  We want to stay in the buffer that we invoked
help from, to get the keybindings from the right keymaps, but we also
want to insert the documentation in the *Help* buffer.  Setting
`standard-output` to the *Help* buffer and using `princ` is just a
convenient way to do that.

The fix is to switch things around so we can use `insert` instead.
We have done that elsewhere in help, and should do the same in
`read-char-choice` also.

Another option is to introduce a version of `princ` that preserves
string properties.