# HG changeset patch # User Alan Mackenzie # Date 1148476932 0 # Node ID 238e43ed886e0e52c5c76916aa6d698d24da79bb # Parent 8740ce7e1367e390c9d215ae8c819ecf123c751d startup.el (command-line): For names of preloaded files, don't append ".elc" (now done in Fload), and call file-truename on the lisp directory. subr.el (eval-after-load): Fix the doc-string. Allow FILE to match ANY loaded file with the right name, not just those in load-path. Put a regexp matching the file name into after-load-alist, rather than the name itself. subr.el: New functions load-history-regexp, load-history-filename-element, do-after-load-evaluation. international/mule.el (load-with-code-conversion): Do the eval-after-load stuff by calling do-after-load-evaluation. diff -r 8740ce7e1367 -r 238e43ed886e lisp/international/mule.el --- a/lisp/international/mule.el Wed May 24 12:05:03 2006 +0000 +++ b/lisp/international/mule.el Wed May 24 13:22:12 2006 +0000 @@ -98,9 +98,9 @@ )) (let (kill-buffer-hook kill-buffer-query-functions) (kill-buffer buffer))) - (let ((hook (assoc file after-load-alist))) - (when hook - (mapcar (function eval) (cdr hook)))) + (unless purify-flag + (do-after-load-evaluation fullname)) + (unless (or nomessage noninteractive) (if source (message "Loading %s (source)...done" file) diff -r 8740ce7e1367 -r 238e43ed886e lisp/startup.el --- a/lisp/startup.el Wed May 24 12:05:03 2006 +0000 +++ b/lisp/startup.el Wed May 24 13:22:12 2006 +0000 @@ -644,18 +644,17 @@ ;; Convert preloaded file names to absolute. (let ((lisp-dir - (file-name-directory - (locate-file "simple" load-path - (get-load-suffixes))))) + (file-truename + (file-name-directory + (locate-file "simple" load-path + (get-load-suffixes)))))) (setq load-history (mapcar (lambda (elt) (if (and (stringp (car elt)) (not (file-name-absolute-p (car elt)))) (cons (concat lisp-dir - (car elt) - (if (string-match "[.]el$" (car elt)) - "" ".elc")) + (car elt)) (cdr elt)) elt)) load-history))) diff -r 8740ce7e1367 -r 238e43ed886e lisp/subr.el --- a/lisp/subr.el Wed May 24 12:05:03 2006 +0000 +++ b/lisp/subr.el Wed May 24 13:22:12 2006 +0000 @@ -1393,32 +1393,94 @@ t)) nil)) +(defun load-history-regexp (file) + "Form a regexp to find FILE in load-history. +FILE, a string, is described in eval-after-load's doc-string." + (if (file-name-absolute-p file) + (setq file (file-truename file))) + (concat (if (file-name-absolute-p file) "\\`" "\\<") + (regexp-quote file) + (if (file-name-extension file) + "" + ;; Note: regexp-opt can't be used here, since we need to call + ;; this before Emacs has been fully started. 2006-05-21 + (concat "\\(" (mapconcat 'regexp-quote load-suffixes "\\|") "\\)?")) + "\\(" (mapconcat 'regexp-quote jka-compr-load-suffixes "\\|") + "\\)?\\'")) + +(defun load-history-filename-element (file-regexp) + "Get the first elt of load-history whose car matches FILE-REGEXP. +Return nil if there isn't one." + (let* ((loads load-history) + (load-elt (and loads (car loads)))) + (save-match-data + (while (and loads + (or (null (car load-elt)) + (not (string-match file-regexp (car load-elt))))) + (setq loads (cdr loads) + load-elt (and loads (car loads))))) + load-elt)) + (defun eval-after-load (file form) "Arrange that, if FILE is ever loaded, FORM will be run at that time. -This makes or adds to an entry on `after-load-alist'. If FILE is already loaded, evaluate FORM right now. -It does nothing if FORM is already on the list for FILE. -FILE must match exactly. Normally FILE is the name of a library, -with no directory or extension specified, since that is how `load' -is normally called. -FILE can also be a feature (i.e. a symbol), in which case FORM is -evaluated whenever that feature is `provide'd." - (let ((elt (assoc file after-load-alist))) - ;; Make sure there is an element for FILE. - (unless elt (setq elt (list file)) (push elt after-load-alist)) - ;; Add FORM to the element if it isn't there. + +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, it is first converted to a true name by chasing +out symbolic links. Only a file of this name \(see next paragraph for +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 whenever that feature is `provide'd. + +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'." + ;; Add this FORM into after-load-alist (regardless of whether we'll be + ;; evaluating it now). + (let* ((regexp-or-feature + (if (stringp file) (load-history-regexp file) file)) + (elt (assoc regexp-or-feature after-load-alist))) + (unless elt + (setq elt (list regexp-or-feature)) + (push elt after-load-alist)) + ;; Add FORM to the element unless it's already there. (unless (member form (cdr elt)) - (nconc elt (list form)) - ;; If the file has been loaded already, run FORM right away. - (if (if (symbolp file) - (featurep file) - ;; Make sure `load-history' contains the files dumped with - ;; Emacs for the case that FILE is one of them. - ;; (load-symbol-file-load-history) - (when (locate-library file) - (assoc (locate-library file) load-history))) - (eval form)))) - form) + (nconc elt (list form))) + + ;; Is there an already loaded file whose name (or `provide' name) + ;; matches FILE? + (if (if (stringp file) + (load-history-filename-element regexp-or-feature) + (featurep file)) + (eval form)))) + +(defun do-after-load-evaluation (abs-file) + "Evaluate all `eval-after-load' forms, if any, for ABS-FILE. +ABS-FILE, a string, should be the absolute true name of a file just loaded." + (let ((after-load-elts after-load-alist) + a-l-element file-elements file-element form) + (while after-load-elts + (setq a-l-element (car after-load-elts) + after-load-elts (cdr after-load-elts)) + (when (and (stringp (car a-l-element)) + (string-match (car a-l-element) abs-file)) + (while (setq a-l-element (cdr a-l-element)) ; discard the file name + (setq form (car a-l-element)) + (eval form)))))) (defun eval-next-after-load (file) "Read the following input sexp, and run it whenever FILE is loaded.