Wilfred / helpful

A better Emacs *help* buffer
1.1k stars 62 forks source link

No locations on defun's defined by macro's (e.g. use-package :defer t) #18

Open unhammer opened 7 years ago

unhammer commented 7 years ago

(originally at https://www.reddit.com/r/emacs/comments/6x2pnx/helpful_adding_contextual_help_to_emacs/dmddom3/ ) I'm not sure if this is a bug or just something that's impossible to do, but there's no location info on my-foo when you do emacs -Q and eval-buffer on the below file:

(package-initialize)
(use-package counsel
  :defer t
  :config
  (defun my-foo (x)
    (with-ivy-window
      (insert x))))
(require 'counsel)
(require 'helpful)
(helpful-function 'my-foo)

But if you do C-M-x on the defun, you will get location info.

Also, if you eval-buffer twice, you'll also get location info. So presumably it's the eval-after-load that doesn't bother with carrying around location, which makes sense.

Weird thing: If I remove the :defer t, I don't get location info from helpful, but when I afterwards try plain C-h f, it shows the location, and then doing helpful-function after that shows the location.

Wilfred commented 7 years ago

OK, so I think this is due to load-history. We call find-function-noselect, which calls find-function-library and that inspects load-history with symbol-file.

When you run eval-buffer on a file foo.el, load-history will contain:

("/tmp/foo.el"
  (require . finder-inf)
  (defun . my-foo)
  (require . counsel)
  (require . helpful))

However, it looks like load-history is only updated once eval-buffer is finished. Since you're running helpful-function in the same file, eval-buffer isn't finished and load-history doesn't contain foo.el.

If you put the following in an elisp file:

(package-initialize)
(use-package counsel
  :defer t
  :config
  (defun my-foo4 (x)
    (with-ivy-window
      (insert x))))
(require 'counsel)

M-x eval-buffer and then M-x helpful-function my-foo shows the position as expected.

That solves the example you've given, but I imagine you're not actually running helpful-function from the same file as you've written use-package. How did you originally encounter this issue?

unhammer commented 7 years ago

Well, another way to make it happen is to C-M-x one statement at a time in the buffer. Then my-foo defined inside the use-package will not have a location, while if it's defined outside use-package it'll have a location. I think that may be how I originally encountered it, writing use-package statements and doing C-M-x on them (though I have a feeling I've seen it too often for that to be the only situation).