4

Using benchmark-init, I see that helm files (helm-elisp, helm-mode, helm, etc.) are being required, but I don't have "(require 'helm)" or "(require 'helm-config)" or "(helm-mode 1)" anywhere in my init file. I'm using use-package, and all helm-related packages are deferred, including helm. Is there some direct way I can figure out where helm is being required from? I also want to find out where semantic is being required from.

Drew
  • 75,699
  • 9
  • 109
  • 225
noctuid
  • 429
  • 3
  • 11
  • Maybe it is caused by benchmark-init, you should also put `(benchmark-init/show-durations-tree)` (or similar) at the end of your `init.el`, instead of running it with `M-x` (if it is `helm-M-x`, many helm-* requires might be made in a single `helm-M-x`). I guess benchmark-init doesn't know (and doesn't care) when Emacs initialization is finished. – xuchunyang Sep 24 '15 at 04:32
  • It does have a `(benchmark-init/deactivate)`. I had just made the mistake of not uncommenting it; thanks! That fixes the helm part of my problem. – noctuid Sep 24 '15 at 16:09
  • Your solution is better, I am unfamiliar with benchmark-init (and its doc seems not good). So now, you know helm is being required when you first use helm's function and at the time if benchmark-init is not deactivated, it will also display requiring info of helm. – xuchunyang Sep 24 '15 at 16:36

1 Answers1

4

I don't know of any standard way of doing this. However, you can fairly simply advice require so that it keeps trace of who calls it.

(defvar my/require-tree nil)
(defun require--advice (orig-fun feature &rest args)
  (setq my/require-tree
    (append my/require-tree
        (list (let ((my/require-tree (list feature)))
            (apply orig-fun feature args)
            my/require-tree)))))
(advice-add 'require :around 'require--advice)

If you put this at the beginning of your init file, you should at the end get something like this in the my/require-tree variable:

((org
  (calendar
   (cal-menu
    (calendar)))
  (find-func)
  (format-spec)
  (org-macs)
  (org-compat
   (org-macs))
  (ob-emacs-lisp
   (ob
    (org-macs)
    (org-compat)
    (ob-eval
     (org-macs))
    (ob-core
     (ob-eval)
     (org-macs)
     (org-compat))
    (ob-comint
     (ob-core)
     (org-compat)
     (comint))
    (ob-exp
     (ob-core))))
  ;;...
  )
 (tramp
  ;;...
  ))

NB: You can use C-hvmy/require-treeRET to see the contents of the variable in a nicely formatted way.

François Févotte
  • 5,917
  • 1
  • 24
  • 37
  • Thanks! This gives a somewhat better overview than benchmark/init. However, there are still some things at the top level that I'm confused about. For example, paredit appears at the top level (and the only package I use that requires paredit is autoloaded). I don't use linum either, but it is being required. I'm also curious as to where some libraries like f.el are first being loaded. – noctuid Sep 24 '15 at 16:20