]> code.delx.au - gnu-emacs/blobdiff - lisp/loadhist.el
*** empty log message ***
[gnu-emacs] / lisp / loadhist.el
index 8df66d3bcc97306299d13d1d57257655e8f0a1ac..e609596e4a8e0c4502aa970548cdfa783a28c351 100644 (file)
@@ -1,9 +1,9 @@
 ;;; loadhist.el --- lisp functions for working with feature groups
 
-;; Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1995, 1998, 2000 Free Software Foundation, Inc.
 
 ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
-;; Version: 1.0
+;; Maintainer: FSF
 ;; Keywords: internal
 
 ;; This file is part of GNU Emacs.
 
 ;;; Code:
 
-(defvar load-history-loaded nil
-  "Non-nil means we have loaded the file `fns-VERSION.el' in `exec-directory'.
-That file records the part of `load-history' for preloaded files,
-which is cleared out before dumping to make Emacs smaller.")
-
-(defun symbol-file (sym)
-  "Return the input source from which SYM was loaded.
-This is a file name, or nil if the source was a buffer with no associated file."
-  (unless load-history-loaded
-    (load (expand-file-name
-          ;; fns-XX.YY.ZZ.el does not work on DOS filesystem.
-          (convert-standard-filename (format "fns-%s.el" emacs-version))
-          exec-directory)
-         ;; The file name fns-%s.el already has a .el extension.
-         nil nil t)
-    (setq load-history-loaded t))
-  (catch 'foundit
-    (mapcar
-     (function (lambda (x) (if (memq sym (cdr x)) (throw 'foundit (car x)))))
-     load-history)
-    nil))
-
 (defun feature-symbols (feature)
-  "Return the file and list of symbols associated with a given FEATURE."
+  "Return the file and list of definitions associated with FEATURE.
+The value is actually the element of `load-history'
+for the file that did (provide FEATURE)."
    (catch 'foundit
-     (mapcar
-      (function (lambda (x) 
-                 (if (member (cons 'provide feature) (cdr x))
-                     (throw 'foundit x))))
-      load-history)
+     (mapc (lambda (x)
+            (if (member (cons 'provide feature) (cdr x))
+                (throw 'foundit x)))
+          load-history)
      nil))
 
 (defun feature-file (feature)
   "Return the file name from which a given FEATURE was loaded.
 Actually, return the load argument, if any; this is sometimes the name of a
-Lisp file without an extension.  If the feature came from an eval-buffer on
-a buffer with no associated file, or an eval-region, return nil."
+Lisp file without an extension.  If the feature came from an `eval-buffer' on
+a buffer with no associated file, or an `eval-region', return nil."
   (if (not (featurep feature))
-      (error "%s is not a currently loaded feature" (symbol-name feature))
+      (error "%S is not a currently loaded feature" feature)
     (car (feature-symbols feature))))
 
 (defun file-provides (file)
   "Return the list of features provided by FILE."
-  (let ((symbols (cdr (assoc file load-history))) (provides nil))
-    (mapcar
-     (function (lambda (x)
-                (if (and (consp x) (eq (car x) 'provide))
-                    (setq provides (cons (cdr x) provides)))))
-     symbols)
-    provides
-    ))
+  (let ((symbols (cdr (assoc file load-history)))
+       provides)
+    (mapc (lambda (x)
+           (if (and (consp x) (eq (car x) 'provide))
+               (setq provides (cons (cdr x) provides))))
+         symbols)
+    provides))
 
 (defun file-requires (file)
   "Return the list of features required by FILE."
-  (let ((symbols (cdr (assoc file load-history))) (requires nil))
-    (mapcar
-     (function (lambda (x)
-                (if (and (consp x) (eq (car x) 'require))
-                    (setq requires (cons (cdr x) requires)))))
-     symbols)
-    requires
-    ))
-
-(defun file-set-intersect (p q)
-  ;; Return the set intersection of two lists
+  (let ((symbols (cdr (assoc file load-history)))
+       requires)
+    (mapc (lambda (x)
+           (if (and (consp x) (eq (car x) 'require))
+               (setq requires (cons (cdr x) requires))))
+         symbols)
+    requires))
+
+(defsubst file-set-intersect (p q)
+  "Return the set intersection of two lists."
   (let ((ret nil))
-    (mapcar
-     (function (lambda (x) (if (memq x q) (setq ret (cons x ret)))))
-     p)
-    ret
-    ))
+    (dolist (x p ret)
+      (if (memq x q) (setq ret (cons x ret))))
+    ret))
 
 (defun file-dependents (file)
   "Return the list of loaded libraries that depend on FILE.
 This can include FILE itself."
-  (let ((provides (file-provides file)) (dependents nil))
-    (mapcar
-     (function (lambda (x) 
-                (if (file-set-intersect provides (file-requires (car x)))
-                    (setq dependents (cons (car x) dependents)))))
-     load-history)
-    dependents
-    ))
+  (let ((provides (file-provides file))
+       (dependents nil))
+    (dolist (x load-history dependents)
+      (if (file-set-intersect provides (file-requires (car x)))
+         (setq dependents (cons (car x) dependents))))
+    dependents))
 
 (defun read-feature (prompt)
   "Read a feature name \(string\) from the minibuffer.
 Prompt with PROMPT and completing from `features', and
 return the feature \(symbol\)."
   (intern (completing-read prompt
-                          (mapcar (function (lambda (feature)
-                                              (list (symbol-name feature))))
+                          (mapcar (lambda (feature)
+                                    (list (symbol-name feature)))
                                   features)
                           nil t)))
 
 (defvar loadhist-hook-functions
-  '(after-change-function after-change-functions
-after-insert-file-functions auto-fill-function before-change-function
-before-change-functions blink-paren-function
-buffer-access-fontify-functions command-line-functions
-comment-indent-function kill-buffer-query-functions
-kill-emacs-query-functions lisp-indent-function
-redisplay-end-trigger-functions temp-buffer-show-function
-window-scroll-functions window-size-change-functions
-write-region-annotate-functions)
-  "A list of special hooks from the `Standard Hooks' node of the Lisp manual.
+  '(after-change-functions
+    after-insert-file-functions auto-fill-function
+    before-change-functions blink-paren-function
+    buffer-access-fontify-functions command-line-functions
+    comment-indent-function kill-buffer-query-functions
+    kill-emacs-query-functions lisp-indent-function
+    mouse-position-function
+    redisplay-end-trigger-functions temp-buffer-show-function
+    window-scroll-functions window-size-change-functions
+    write-region-annotate-functions)
+  "A list of special hooks from Info node `(elisp)Standard Hooks'.
 
 These are symbols with hook-type values whose names don't end in
 `-hook' or `-hooks', from which `unload-feature' tries to remove
@@ -144,9 +118,9 @@ pertinent symbols.")
 ;;;###autoload
 (defun unload-feature (feature &optional force)
   "Unload the library that provided FEATURE, restoring all its autoloads.
-If the feature is required by any other loaded code, and optional FORCE
+If the feature is required by any other loaded code, and prefix arg FORCE
 is nil, raise an error."
-  (interactive (list (read-feature "Feature: ")))
+  (interactive (list (read-feature "Feature: ") current-prefix-arg))
   (if (not (featurep feature))
       (error "%s is not a currently loaded feature" (symbol-name feature)))
   (if (not force)
@@ -178,22 +152,36 @@ is nil, raise an error."
          (if (or (and (boundp x)        ; Random hooks.
                       (consp (symbol-value x))
                       (string-match "-hooks?\\'" (symbol-name x)))
-                 (and (fboundp x)       ; Known abnormal hooks etc.
+                 (and (boundp x)       ; Known abnormal hooks etc.
                       (memq x loadhist-hook-functions)))
-             (mapcar (lambda (y) (remove-hook x y))
-                     (cdr flist))))))
-    (mapcar
-     (lambda (x) 
+            (dolist (y (cdr flist))
+              (remove-hook x y))))))
+    (if (fboundp 'elp-restore-function)        ; remove ELP stuff first
+       (dolist (elt (cdr flist))
+         (if (symbolp elt)
+             (elp-restore-function elt))))
+    (mapc
+     (lambda (x)
        (cond ((stringp x) nil)
              ((consp x)
               ;; Remove any feature names that this file provided.
               (if (eq (car x) 'provide)
-                  (setq features (delq (cdr x) features))))
-             ((boundp x) (makunbound x))
-             ((fboundp x)
-              (fmakunbound x)
-              (let ((aload (get x 'autoload)))
-                (if aload (fset x (cons 'autoload aload)))))))
+                  (setq features (delq (cdr x) features)))
+              (when (eq (car x) 'defvar)
+               ;; Kill local values as much as possible.
+               (dolist (buf (buffer-list))
+                 (with-current-buffer buf
+                   (kill-local-variable (cdr x))))
+               ;; Get rid of the default binding if we can.
+               (unless (local-variable-if-set-p (cdr x))
+                 (makunbound (cdr x)))))
+            (t
+             (when (fboundp x)
+               (if (fboundp 'ad-unadvise)
+                   (ad-unadvise x))
+               (fmakunbound x)
+               (let ((aload (get x 'autoload)))
+                 (if aload (fset x (cons 'autoload aload))))))))
      (cdr flist))
     ;; Delete the load-history element for this file.
     (let ((elt (assoc file load-history)))