2

I have a package that enhances the functionality of another package. To save the user the effort of any additional configurating, I would like my package to load automatically if the larger package loads.

(In my example, my package is a Flycheck checker, but I don’t think this situation will be specific to Flycheck checkers).

Is there a standard idiom for achieving this?


I find myself tempted to put the following at the end of my package:

;;;###autoload
(with-eval-after-load 'flycheck
  (unless (featurep 'flycheck-mychecker)
    (require 'flycheck-mychecker)))

Now, package-lint tells me:

warning: `with-eval-after-load' is for use in configurations, and should rarely be used in packages

However, I couldn’t find an explanation of why this is typically bad in packages, and in what circumstances the “rarely used” exception should apply.

Drew
  • 75,699
  • 9
  • 109
  • 225
mavit
  • 211
  • 1
  • 5

1 Answers1

2
  1. Use autoload for specific commands etc.

  2. Use require if your library depends on another. That's the main question to ask yourself: does your library need the other library? If so, require it.

    You can also use a "soft-require" if you want to load another library whenever something is true. For example:

(when (fboundp 'foobar) (require 'foo nil t))
  1. Use with-eval-after-load (or eval-after-load) if you want to do something after some other library is loaded:
(with-eval-after-load 'bar
  ;; ...
  )

I imagine that the "rarely used" just means that most libraries explicitly use require or they autoload stuff. The doc of with-eval-after-load and eval-after-load describes their behavior, which in turn defines their use cases. Don't use them when you don't need them; that's all I think that "rarely used" intends.

On the other hand, presumably your package is intended to be optional. In that case, it's enough that a user explicitly loads it. And in that case all you need to do is require the larger package at the outset of your code. I imagine that this is also part of what the text you quote intends.


A final note. If you want to load a library again, or load a library with the same name as one that's already been loaded (e.g. to pick up some other variant of version of it), then use load-library, not require. And if you want to load the source file (*.el) then explicitly include the .el in the argument to load-library.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • "presumably your package is intended to be optional" -- I admit that wasn't my intention. I'd expect a user to want to configure which major modes a Flycheck checker applies to (which they can via customization), but I find it surprising that a user might want to install a package but never load it. – mavit Aug 07 '21 at 20:53
  • @mavit: It's optional whether to download, install, and load a package. Using a package (in any way) is a user choice - that was my point. – Drew Aug 08 '21 at 00:40