For years I've used the
rgr/context-help solution from the EmacsWiki for this, with some slight tweaks. A few aspects still bothered me, though, so this question inspired me to write a new variant of that as a global minor mode. Among other differences, this utilises
help-xref-interned to display all (variable, function, face) kinds of help for a symbol instead of arbitrarily choosing between
describe-variable when both cells are defined.
"Show help for the elisp symbol at point in the current *Help* buffer.
:lighter " C-h"
(require 'help-mode) ;; for `help-xref-interned'
(when (eq this-command 'my-contextual-help-mode)
(message "Contextual help is %s" (if my-contextual-help-mode "on" "off")))
(if (fboundp 'eldoc-current-symbol)
(defadvice eldoc-print-current-symbol-info (before my-contextual-help activate)
"Triggers contextual elisp *Help*. Enabled by `my-contextual-help-mode'."
(defvar-local my-contextual-help-last-symbol nil
;; Using a buffer-local variable for this means that we can't
;; trigger changes to the help buffer simply by switching windows,
;; which seems generally preferable to the alternative.
"The last symbol processed by `my-contextual-help' in this buffer.")
(defun my-contextual-help (&optional force)
"Describe function, variable, or face at point, if *Help* buffer is visible."
(let ((help-visible-p (get-buffer-window (help-buffer))))
(when (or help-visible-p force)
(let ((sym (if (fboundp 'eldoc-current-symbol)
;; We ignore keyword symbols, as their help is redundant.
;; If something else changes the help buffer contents, ensure we
;; don't immediately revert back to the current symbol's help.
(and (not (keywordp sym))
(or (not (eq sym my-contextual-help-last-symbol))
(and force (not help-visible-p)))
(setq my-contextual-help-last-symbol sym)
(defun my-contextual-help-toggle ()
"Intelligently enable or disable `my-contextual-help-mode'."
(if (get-buffer-window (help-buffer))