3

I'm looking for something similar to Eldoc mode (hover over a function and the parameter list appears in the minibuffer), only I'd like to have a help buffer appear, as if I had just run describe-function. Is there a minor mode that will do this?

Having the help buffer be in a separate frame would be ideal, but I can figure that out at a later point. Funnily enough, I think I saw something like this for SLIME, but I haven't been able to find it again.

1 Answers1

2

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-function and describe-variable when both cells are defined.

(define-minor-mode my-contextual-help-mode
  "Show help for the elisp symbol at point in the current *Help* buffer.

Advises `eldoc-print-current-symbol-info'."
  :lighter " C-h"
  :global t
  (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")))
  (and my-contextual-help-mode
       (eldoc-mode 1)
       (if (fboundp 'eldoc-current-symbol)
           (eldoc-current-symbol)
         (elisp--current-symbol))
       (my-contextual-help :force)))

(defadvice eldoc-print-current-symbol-info (before my-contextual-help activate)
  "Triggers contextual elisp *Help*. Enabled by `my-contextual-help-mode'."
  (and my-contextual-help-mode
       (derived-mode-p 'emacs-lisp-mode)
       (my-contextual-help)))

(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)
                     (eldoc-current-symbol)
                   (elisp--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)
             sym
             (save-selected-window
               (help-xref-interned sym)))))))

(defun my-contextual-help-toggle ()
  "Intelligently enable or disable `my-contextual-help-mode'."
  (interactive)
  (if (get-buffer-window (help-buffer))
      (my-contextual-help-mode 'toggle)
    (my-contextual-help-mode 1)))

(my-contextual-help-mode 1)
phils
  • 48,657
  • 3
  • 76
  • 115
  • Thanks for the quick response! This is pretty close to what I was looking for. Is there any way to make it fully replace Eldoc? That is, not have to open a preliminary Help buffer? It may sound somewhat annoying, but in that case I would toggle it with a keybinding or try to have a dedicated Help buffer frame that it would occupy. –  May 08 '16 at 16:14
  • Blimey I wrote that yonks ago and totally forgot. The elisp is a mess. But nice to know it was used. You have an update? This code reports (eldoc-current-symbol) doesn't exist. – RichieHH Feb 24 '20 at 21:05
  • Changing (eldoc-current-symbol) to (symbol-at-point) works. – RichieHH Feb 24 '20 at 21:16
  • 1
    Hi @RichieHH :) Thanks for putting that code on the Wiki in the first place -- very helpful. I'd subsequently made further changes to this in my own config, so I've updated the answer. `elisp--current-symbol` is the exact same code as the old `eldoc-current-symbol`, so I used that for consistency. – phils Feb 24 '20 at 23:06
  • Works well. You should replace my old beginner's junk on the wiki page with your stuff. – RichieHH Feb 24 '20 at 23:24
  • 1
    Sure; I've updated that page too. – phils Feb 25 '20 at 00:06
  • 1
    FF to 2021 and I created this as an exercise in making my own minor mode and learning customisation. It loads packages you wont need but the idea is there. https://github.com/rileyrg/el-docstring-sap – RichieHH May 01 '21 at 08:29