Skip to content

transient--describe-function: handle describe-function overrides#431

Merged
tarsius merged 1 commit intomagit:mainfrom
benthamite:fix/describe-function-override-compat
Mar 10, 2026
Merged

transient--describe-function: handle describe-function overrides#431
tarsius merged 1 commit intomagit:mainfrom
benthamite:fix/describe-function-override-compat

Conversation

@benthamite
Copy link
Contributor

@benthamite benthamite commented Mar 10, 2026

Problem

transient--describe-function captures the help buffer via temp-buffer-window-setup-hook. This works with the built-in describe-function, which displays its output via with-help-window and therefore triggers the hook.

However, a common pattern in the Emacs community is to override describe-function with packages like helpful:

(advice-add 'describe-function :override #'helpful-function)

This is recommended by Doom Emacs, Spacemacs, and countless dotfiles. helpful-function creates and displays its buffer via pop-to-buffer rather than with-help-window, so temp-buffer-window-setup-hook never fires, buffer stays nil, and (set-buffer nil) signals (wrong-type-argument stringp nil).

This means pressing ? followed by a suffix key in any transient menu errors out for anyone using this pattern.

Fix

     (describe-function fn)
-    (set-buffer buffer))
+    (when buffer (set-buffer buffer)))

When the hook fires (standard describe-function), behavior is unchanged. When it doesn't (helpful or any other override that bypasses with-help-window), we skip the set-buffer call entirely — the override's pop-to-buffer already selected the correct window and set the current buffer, so no further action is needed.

Context

This is in the spirit of the robustness improvements in #208 and #213, which led to commit 732ec97 rewriting transient--describe-function because it was "too fragile" — it assumed (help-buffer) would return the correct buffer, which broke when packages like epithet renamed help buffers. The current implementation replaced that assumption with temp-buffer-window-setup-hook, but this hook has the same fragility when describe-function itself is replaced with something that doesn't use with-help-window.

benthamite added a commit to benthamite/dotfiles that referenced this pull request Mar 10, 2026
@tarsius
Copy link
Member

tarsius commented Mar 10, 2026

Do we even have to call set-buffer in that case, or would (when buffer (set-buffer buffer)) be more appropriate?

@benthamite benthamite force-pushed the fix/describe-function-override-compat branch from 8242b32 to 80f3779 Compare March 10, 2026 17:33
@benthamite
Copy link
Contributor Author

Good point — updated. When the hook doesn't fire, the override's pop-to-buffer has already selected the window and set the current buffer, so there's nothing for set-buffer to do.

`transient--describe-function' captures the help buffer via
`temp-buffer-window-setup-hook'. This works with the built-in
`describe-function', which displays its output via
`with-help-window' and therefore triggers the hook.

However, a common pattern in the Emacs community is to override
`describe-function' with a function provided by a packages like
`helpful'.  `helpful-function' creates and displays its buffer
via `pop-to-buffer' rather than `with-help-window', so
`temp-buffer-window-setup-hook' never fires and `buffer' stays
nil, causing (set-buffer nil) to signal `wrong-type-argument'.

See magit#431.
@tarsius tarsius force-pushed the fix/describe-function-override-compat branch from 80f3779 to 56c601e Compare March 10, 2026 20:32
@tarsius tarsius merged commit 56c601e into magit:main Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants