Function: eval-after-load
eval-after-load is a byte-compiled function defined in subr.el.gz.
Signature
(eval-after-load FILE FORM)
Documentation
Arrange that if FILE is loaded, FORM will be run immediately afterwards.
If FILE is already loaded, evaluate FORM right now.
FORM can be an Elisp expression (in which case it's passed to eval),
or a function (in which case it's passed to funcall with no argument).
If a matching file is loaded again, FORM will be evaluated again.
If FILE is a string, it may be either an absolute or a relative file name, and may have an extension (e.g. ".el") or may lack one, and additionally may or may not have an extension denoting a compressed format (e.g. ".gz").
When FILE is absolute, this first converts it to a true name by chasing symbolic links. Only a file of this name (see next paragraph regarding extensions) will trigger the evaluation of FORM. When FILE is relative, a file whose absolute true name ends in FILE will trigger evaluation.
When FILE lacks an extension, a file name with any extension will trigger evaluation. Otherwise, its extension must match FILE's. A further extension for a compressed format (e.g. ".gz") on FILE will not affect this name matching.
Alternatively, FILE can be a feature (i.e. a symbol), in which case FORM
is evaluated at the end of any file that provides this feature.
If the feature is provided when evaluating code not associated with a
file, FORM is evaluated immediately after the provide statement.
Usually FILE is just a library name like "font-lock" or a feature name
like font-lock.
This function makes or adds to an entry on after-load-alist.
See also with-eval-after-load.
Probably introduced at or before Emacs version 19.29.
Source Code
;; Defined in /usr/src/emacs/lisp/subr.el.gz
(defun eval-after-load (file form)
"Arrange that if FILE is loaded, FORM will be run immediately afterwards.
If FILE is already loaded, evaluate FORM right now.
FORM can be an Elisp expression (in which case it's passed to `eval'),
or a function (in which case it's passed to `funcall' with no argument).
If a matching file is loaded again, FORM will be evaluated again.
If FILE is a string, it may be either an absolute or a relative file
name, and may have an extension (e.g. \".el\") or may lack one, and
additionally may or may not have an extension denoting a compressed
format (e.g. \".gz\").
When FILE is absolute, this first converts it to a true name by chasing
symbolic links. Only a file of this name (see next paragraph regarding
extensions) will trigger the evaluation of FORM. When FILE is relative,
a file whose absolute true name ends in FILE will trigger evaluation.
When FILE lacks an extension, a file name with any extension will trigger
evaluation. Otherwise, its extension must match FILE's. A further
extension for a compressed format (e.g. \".gz\") on FILE will not affect
this name matching.
Alternatively, FILE can be a feature (i.e. a symbol), in which case FORM
is evaluated at the end of any file that `provide's this feature.
If the feature is provided when evaluating code not associated with a
file, FORM is evaluated immediately after the provide statement.
Usually FILE is just a library name like \"font-lock\" or a feature name
like `font-lock'.
This function makes or adds to an entry on `after-load-alist'.
See also `with-eval-after-load'."
(declare (indent 1)
(compiler-macro
(lambda (whole)
(if (eq 'quote (car-safe form))
;; Quote with lambda so the compiler can look inside.
`(eval-after-load ,file (lambda () ,(nth 1 form)))
whole))))
;; Add this FORM into after-load-alist (regardless of whether we'll be
;; evaluating it now).
(let* ((regexp-or-feature
(if (stringp file)
(setq file (load-history-regexp file))
file))
(elt (assoc regexp-or-feature after-load-alist))
(func
(if (functionp form) form
;; Try to use the "current" lexical/dynamic mode for `form'.
(eval `(lambda () ,form) lexical-binding))))
(unless elt
(setq elt (list regexp-or-feature))
(push elt after-load-alist))
;; Is there an already loaded file whose name (or `provide' name)
;; matches FILE?
(prog1 (if (if (stringp file)
(load-history-filename-element regexp-or-feature)
(featurep file))
(funcall func))
(let ((delayed-func
(if (not (symbolp regexp-or-feature)) func
;; For features, the after-load-alist elements get run when
;; `provide' is called rather than at the end of the file.
;; So add an indirection to make sure that `func' is really run
;; "after-load" in case the provide call happens early.
(lambda ()
(if (not load-file-name)
;; Not being provided from a file, run func right now.
(funcall func)
(let ((lfn load-file-name)
;; Don't use letrec, because equal (in
;; add/remove-hook) could get trapped in a cycle
;; (bug#46326).
(fun (make-symbol "eval-after-load-helper")))
(fset fun (lambda (file)
(when (equal file lfn)
(remove-hook 'after-load-functions fun)
(funcall func))))
(add-hook 'after-load-functions fun 'append)))))))
;; Add FORM to the element unless it's already there.
(unless (member delayed-func (cdr elt))
(nconc elt (list delayed-func)))))))