10

I've been updating all my use-package calls now that :idle is no longer a decent way to defer stuff. At the moment one of the biggest hits on my load time is elpy which loads a whole bunch of additional modules. At the moment my invocation is rather basic:

(use-package elpy
  :commands elpy-enable
  :init (elpy-enable)
  :config
  (progn
    (setq elpy-rpc-backend "jedi"
          elpy-rpc-project-specific 't)
    (when (fboundp 'flycheck-mode)
      (setq elpy-modules (delete 'elpy-module-flymake elpy-modules)))))

However this is rather wasteful if I'm never editing any python modules. The trouble is elpy is a collection of modes so I can't just use the mode binding form as elpy-enable needs to get called. So what approach should I use. Is it just a case of triggering on the python-mode hook?

stsquad
  • 4,626
  • 28
  • 45
  • I just stopped tracking the MELPA version of use-package. It seems :idle was removed with nothing to replace it. I'll just wait until a replacement pops up. – abo-abo Mar 17 '15 at 09:21
  • @abo-abo: I can understand why, :idle is a bit of a hack. Really for proper on-demand loading it should be triggered by an event other than "some time passed". – stsquad Mar 17 '15 at 10:02
  • 2
    `:idle` can be replaced with something like `:defer 30` where the number is the delay in seconds after which the package should be loaded. – Kaushal Modi Mar 17 '15 at 10:39
  • @kaushalmodi, does that already work? – abo-abo Mar 17 '15 at 10:40
  • @abo-abo I haven't tried but it probably should. I read that update in yesterday's commit. The README is also updated with that info. – Kaushal Modi Mar 17 '15 at 10:41
  • If you rarely use Python and you need to call `elpy-enable` to be able to use elpy then I would call the whole `(use-package elpy ..)` in the `python-mode-hook` without `:init` and `:commands` sections and put `(elpy-enable)` as the last form in `:config`. – Kaushal Modi Mar 17 '15 at 10:51

3 Answers3

7

I don’t know Elpy, so I’m not sure whether I understand your problem correctly. I do know use-package, though, and recently suffered from the very same issue, namely the removal of :idle.

Basically, there are two ways out, depending on how you need to use Elpy. You can either use a poor man’s :idle, with run-with-idle-timer, e.g.

:init (run-with-idle-timer 10 nil #'elpy-enable)

Alternatively, you can rely on good old with-eval-after-load or use python-mode-hook and delay Elpy until after Python Mode is loaded or enabled respectively:

:init (add-hook 'python-mode-hook #'elpy-enable)
;; or
:init (with-eval-after-load 'python (elpy-enable))
  • If elpy was a simple mode it would be fine. However really it's a bunch of minor-modes stitched together to make the python experience more integrated. As such the elpy-enable step has to be run before the first python file is loaded so all the modules are configured and ready. – stsquad Mar 17 '15 at 20:48
  • @stsquad with-eval-after-load should do exactly that. –  Mar 17 '15 at 21:15
  • 1
    I need to add `:commands elpy-enable` to make it works. `:init (with-eval-after-load 'python (elpy-enable)) :commands elpy-enable` – azzamsa Oct 30 '18 at 05:06
6

The author of elpy suggests doing this via an advice, because elpy-enable modifies the python-mode-hook variable, so calling it inside the mode-hook is too late: https://github.com/jorgenschaefer/elpy/wiki/Configuration

simple approach:

(package-initialize)
(advice-add 'python-mode :before 'elpy-enable)

using use-package:

(use-package elpy :ensure t
  :defer t
  :init
  (advice-add 'python-mode :before 'elpy-enable))
T Nierath
  • 161
  • 1
  • 1
  • 2
    Thanks for finding this when I couldn't. [I've given feedback](https://github.com/jorgenschaefer/elpy/issues/1566#issuecomment-496956436) to the maintainer that IMHO this is the wrong place to hide this information. It's also in the official [`README.rst`](https://github.com/jorgenschaefer/elpy/blob/master/README.rst), but not in the first and most obvious place to look: [the installation section of the documentation](https://elpy.readthedocs.io/en/latest/introduction.html#installation). I've reported this in [issue #1606](https://github.com/jorgenschaefer/elpy/issues/1606). – Adam Spiers May 29 '19 at 14:25
  • This should be the accepted answer. @stsquad, please consider marking this as answer. – Martin Dec 16 '21 at 13:39
2

I think it is possible with :after

(use-package python
  :ensure t
  :defer t
  :mode ("\\.py\\'" . python-mode))

(use-package elpy
  :ensure t
  :after python
  :config (elpy-enable))
tarsius
  • 25,298
  • 4
  • 69
  • 109
  • 1
    Didn't work for me. Also you don't need `:defer` if you already use `:mode`. https://github.com/jwiegley/use-package#notes-about-lazy-loading – azzamsa Oct 30 '18 at 05:08