Subject: Re: bug#78166: 30.1; describe-input-method does not respect help-window-select

From: Sean Devlin <[email-masked]>
Date: Mon, 19 May 2025 12:41:00 -0400

> On May 17, 2025, at 4:03 AM, Eli Zaretskii <[email-masked]> wrote:
> 
>> From: Sean Devlin <[email-masked]>
>> Date: Thu, 1 May 2025 21:52:14 -0400
>> Cc: [email-masked]
>> 
>> 
>> 
>>> On May 1, 2025, at 1:45 PM, Eli Zaretskii <[email-masked]> wrote:
>>> 
>>> 
>>>> 
>>>> From: Sean Devlin <[email-masked]>
>>>> Date: Wed, 30 Apr 2025 17:01:11 -0400
>>>> 
>>>> I see now that the documentation for help-window-select says:
>>>> 
>>>> This option has effect if and only if the help window was created
>>>> by ‘with-help-window’.
>>>> 
>>>> So maybe this is not a bug per se.
>>>> 
>>>> Should we improve quail-help to use with-help-window?
>>> 
>>> Yes, if we want it to heed help-window-select, we should.
>>> 
>>> Patches welcome.  But please be careful and test the changes
>>> thoroughly: AFAIR input-method help has several features thyat we
>>> would not like to lose.
>> 
>> Sounds good. I will give it a try. I’ll mail back here if I run into problems.
> 
> Did you have an opportunity to make some progress with this issue?

Hi Eli,

I did look at this bit, but I think I need some advice on how best to proceed.

I also found a couple other bugs in this code, which I’ll describe below.

As the code stands today, We have the command describe-input-method and its subroutine describe-current-input-method. These functions do some basic setup (e.g. binding help-buffer-under-preparation and calling help-setup-xref), but they delegate the main work to a funcall to describe-current-input-method-function.

The variable describe-current-input-method-function is set by the input method. For example, the function quail-activate sets this to quail-help, so all quail-derived input methods share a common implementation. There are a few other implementations in the Emacs source in hangul.el, robin.el, and uni-input.el. It seems possible there could be third-party packages defining input methods that provide yet more implementations for describe-current-input-method-function, but I haven’t checked.

Since these implementations are all invoked by the common wrapper code in describe-input-method, it seems like it would be good if that function could handle more of the common setup, e.g. by wrapping the funcall to describe-current-input-method-function in a with-help-window stanza. This way, all implementations of that subroutine would benefit, i.e. help-window-select would work correctly for all of them.

The drawback is that this could be a breaking change. Any work the describe-current-input-method-function implementations are doing to set up the help window would become redundant, and it could cause bugs. Obviously, we can fix the implementations that are in-tree, but I’m not sure how it would affect third-party packages.

I think I see three possible approaches we could take:

As described above, set up the help window using with-help-window in the describe-input-method command and remove any help window setup from the subroutines. This could cause issues for downstream packages.
Instead, we could make a fix directly in quail-help. This would work, but it wouldn’t benefit other implementations of describe-current-input-method-function.
We could introduce an alternative to describe-current-input-method-function and call it when it is non-nil. Otherwise, we would continue to call describe-current-input-method-function.

To expand on the third item, suppose we introduced a new variable called (for example) describe-input-method-body-function. It would be responsible for generating the body of the help buffer, but not for the basic setup of the help buffer or window.

In describe-input-method, we’d have some code like the following (simplified):

(cond
 ((and (symbolp describe-input-method-body-function)
       (fboundp describe-input-method-body-function))
  (with-help-window (help-buffer)
    (funcall describe-input-method-body-function)))
 ((and (symbolp describe-current-input-method-function)
       (fboundp describe-current-input-method-function))
  (funcall describe-current-input-method-function))
 (t …))

This way, we could preserve the existing behavior for third-party packages while also making the help window setup more uniform for in-tree implementations (and for any third-party packages that choose to adopt the new variable).

Any advice on which approach to take would be greatly appreciated!

As to the bugs I mentioned above, they are mainly around the management of help-setup-xref. If describe-current-input-method is invoked directly (instead of as a subroutine of describe-input-method), help xrefs will not be set up at all.

To reproduce:

Emacs -Q
Invoke a couple help commands, e.g.
C-h k C-h k
C-h k C-h c
Check that you can use l and r to go back and forwards between the two buffers
In the scratch buffer, C-\ japanese RET
Mouse-3 on the mode line indicator for the input method
In the help buffer, use l and r and see that it doesn’t work correctly:
Pressing l will skip back to the first help buffer
Pressing r will then bring you back to the second help buffer
The input method help buffer is not on the stack at all, so you cannot retrieve it by any combination of l or r inputs

There is a related bug in the error-handling path of describe-input-method where the help xrefs are set up twice, but I’m not sure of a good way to trigger this path.

Should I file a separate bug for these, or just roll a fix into this change?

Thanks!