changeset 112188:28f569136b3e

* lisp/subr.el (eval-after-load): Fix timing for features. (declare-function, undefined, insert-for-yank) (replace-regexp-in-string): Follow checkdoc's recommendations. * doc/lispref/loading.texi (Hooks for Loading): Adjust doc of eval-after-load.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 10 Jan 2011 22:23:04 -0500
parents e371b9b5f88f
children b8f8e953d12f
files doc/lispref/ChangeLog doc/lispref/loading.texi lisp/ChangeLog lisp/subr.el
diffstat 4 files changed, 37 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/doc/lispref/ChangeLog	Mon Jan 10 18:31:47 2011 -0500
+++ b/doc/lispref/ChangeLog	Mon Jan 10 22:23:04 2011 -0500
@@ -1,3 +1,7 @@
+2011-01-11  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* loading.texi (Hooks for Loading): Adjust doc of eval-after-load.
+
 2011-01-02  Eli Zaretskii  <eliz@gnu.org>
 
 	* modes.texi (Emulating Mode Line): Fix last change.
@@ -8884,7 +8888,7 @@
 ;; End:
 
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-    2007, 2008, 2009, 2010  Free Software Foundation, Inc.
+    2007, 2008, 2009, 2010, 2011  Free Software Foundation, Inc.
 
   This file is part of GNU Emacs.
 
--- a/doc/lispref/loading.texi	Mon Jan 10 18:31:47 2011 -0500
+++ b/doc/lispref/loading.texi	Mon Jan 10 22:23:04 2011 -0500
@@ -962,7 +962,8 @@
 @end example
 
 @var{library} can also be a feature (i.e.@: a symbol), in which case
-@var{form} is evaluated when @code{(provide @var{library})} is called.
+@var{form} is evaluated at the end of any file where
+@code{(provide @var{library})} is called.
 
 An error in @var{form} does not undo the load, but does prevent
 execution of the rest of @var{form}.
--- a/lisp/ChangeLog	Mon Jan 10 18:31:47 2011 -0500
+++ b/lisp/ChangeLog	Mon Jan 10 22:23:04 2011 -0500
@@ -1,3 +1,9 @@
+2011-01-11  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* subr.el (eval-after-load): Fix timing for features (bug#7769).
+	(declare-function, undefined, insert-for-yank)
+	(replace-regexp-in-string): Follow checkdoc's recommendations.
+
 2011-01-10  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* calendar/diary-lib.el (diary-mode): Refresh *Calendar* after
--- a/lisp/subr.el	Mon Jan 10 18:31:47 2011 -0500
+++ b/lisp/subr.el	Mon Jan 10 22:23:04 2011 -0500
@@ -1,7 +1,7 @@
 ;;; subr.el --- basic lisp subroutines for Emacs
 
 ;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1999, 2000, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007, 2008, 2009, 2010
+;;   2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
 ;;   Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
@@ -60,7 +60,7 @@
 `defstruct'.
 
 To specify a value for FILEONLY without passing an argument list,
-set ARGLIST to `t'.  This is necessary because `nil' means an
+set ARGLIST to t.  This is necessary because nil means an
 empty argument list, rather than an unspecified one.
 
 Note that for the purposes of `check-declare', this statement
@@ -483,6 +483,7 @@
   (read-kbd-macro keys))
 
 (defun undefined ()
+  "Beep to tell the user this binding is undefined."
   (interactive)
   (ding))
 
@@ -1599,11 +1600,7 @@
 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.  Note that although
-provide statements are usually at the end of files, this is not always
-the case (e.g., sometimes they are at the start to avoid a recursive
-load error).  If your FORM should not be evaluated until the code in
-FILE has been, do not use the symbol form for FILE in such cases.
+is evaluated at the end of any file that `provide's this feature.
 
 Usually FILE is just a library name like \"font-lock\" or a feature name
 like 'font-lock.
@@ -1612,11 +1609,27 @@
   ;; 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 (purecopy (load-history-regexp file))) file))
+	  (if (stringp file)
+              (setq file (purecopy (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))
+    (when (symbolp regexp-or-feature)
+      ;; 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 `form' is really run "after-load" in case the provide
+      ;; call happens early.
+      (setq form
+            `(when load-file-name
+               (let ((fun (make-symbol "eval-after-load-helper")))
+                 (fset fun `(lambda (file)
+                              (if (not (equal file ',load-file-name))
+                                  nil
+                                (remove-hook 'after-load-functions ',fun)
+                                ,',form)))
+                 (add-hook 'after-load-functions fun)))))
     ;; Add FORM to the element unless it's already there.
     (unless (member form (cdr elt))
       (nconc elt (purecopy (list form))))
@@ -1872,7 +1885,7 @@
 The user ends with RET, LFD, or ESC.  DEL or C-h rubs out.
 C-y yanks the current kill.  C-u kills line.
 C-g quits; if `inhibit-quit' was non-nil around this function,
-then it returns nil if the user types C-g, but quit-flag remains set.
+then it returns nil if the user types C-g, but `quit-flag' remains set.
 
 Once the caller uses the password, it can erase the password
 by doing (clear-string STRING)."
@@ -2496,7 +2509,7 @@
 (defvar yank-undo-function)
 
 (defun insert-for-yank (string)
-  "Calls `insert-for-yank-1' repetitively for each `yank-handler' segment.
+  "Call `insert-for-yank-1' repetitively for each `yank-handler' segment.
 
 See `insert-for-yank-1' for more details."
   (let (to)
@@ -3180,7 +3193,7 @@
 REP is either a string used as the NEWTEXT arg of `replace-match' or a
 function.  If it is a function, it is called with the actual text of each
 match, and its value is used as the replacement text.  When REP is called,
-the match-data are the result of matching REGEXP against a substring
+the match data are the result of matching REGEXP against a substring
 of STRING.
 
 To replace only the first match (if any), make REGEXP match up to \\'