Search code examples
emacsautoloadadvising-functions

autoloaded advice to require file before running function


How come when I autoload some function advice, eg.

;;;###autoload
(advice-add 'eclimd-start :before #'(lambda () (require 'some-library))

and then call eclimd-start, the library from which the advice is autoloaded isn't loaded? I thought I would be able to just use the following to get the file with the settings loaded before calling the function as well,

;;;###autoload
(advice-add 'eclimd-start :before (lambda () nil)

In this case the library contains settings to be used by the function eclimd-start. So, as a reproducible example, it could be

(setq eclimd-default-workspace "/hdd/workspace")

;;;###autoload
(defun my-java-hook () nil)

;;;###autoload
(advice-add 'eclimd-start :before 
   #'(lambda () (require 'some-library))

(provide 'some-library)

and the autoloads are created as usual into a file loaded at startup.


Solution

  • The effect of the ;;;###autoload is defined in an ad-hoc way depending on the thing it annotates. For function definitions, it turns into a call to the autoload function that will cause the file to be loaded when the annotated function is called, but for pretty much everything else, the annotated sexp is just copied to the autoload file.

    So in your case, the ;;;###autoload on my-java-hook causes the autoloads file to contain something like (autoload 'my-java-hook "some-library"), but the same ;;;###autoload you placed in front of the advice will simply cause the autoloads file to contain (advice-add 'eclimd-start ...).

    What you can do, tho is:

    ;;;###autoload
    (advice-add 'eclimd-start :before #'my-eclimd-start-advice)
    ;;;###autoload
    (defun my-eclimd-start-advice ()
      ...blablabla...)