[comp.emacs] Is a file loadable?

agw@convent.columbia.edu (Art Werschulz) (08/30/88)

Hi.

Let us say that file "foo" is "loadable" if either foo.elc or foo.el
is in one of the directories in the load-path.

I would like to do the following:
  
   IF foo is loadable THEN
      (autoload 'foo-mode "foo" t t nil)
   ELSE 
      (autoload 'foo-mode "bar" t t nil)

The obvious thing would be to defun a predicate loadable-p, and
procede from there.  Is there anything built-in that I can use, and so
avoid re-inventing the wheel?  Clearly emacs itself has to search the
load-path whenever it has to do a load or autoload.  How can I use
this built-in ability?

Thanks.

	Art Werschulz

 	ARPAnet:  agw@columbia.edu
	USEnet:   ... seismo!columbia!agw
	BITnet:   agw@columbia.edu
	CCNET:    agw@garfield
	ATTnet:   Columbia University (212) 280-3610 280-2736
		  Fordham University  (212) 841-5323 841-5396

Ram-Ashwin@cs.yale.edu (Ashwin Ram) (08/30/88)

In article <5852@columbia.edu>, agw@convent.columbia.edu (Art Werschulz) writes:
> Let us say that file "foo" is "loadable" if either foo.elc or foo.el
> is in one of the directories in the load-path. [...]
> The obvious thing would be to defun a predicate loadable-p, and
> procede from there.  Is there anything built-in that I can use, and so
> avoid re-inventing the wheel?  Clearly emacs itself has to search the
> load-path whenever it has to do a load or autoload.

To generalize this, it would be nice to have a command akin to the "which"
command in Unix that would return the full pathname of the file that would be
loaded were you to execute the load command.  E.g., (where-is-file "rmail")
might return "/usr/local/lib/emacs/lisp/rmail.elc", or nil if the file wasn't
found in the load-path.

-- Ashwin.

janssen@titan.sw.mcc.com (Bill Janssen) (09/01/88)

(defun remove (item list)
  (let ((tmp list)
	(new-list nil)
	)
    (while (consp tmp)
      (if (not (eq item (car tmp)))
	  (setq new-list (append new-list (list (car tmp)))))
      (setq tmp (cdr tmp))
      )
    new-list
    ))

(defun make-which-list (file)
  "Find out what FILE would be loaded with the current load-path."
  (remove nil (mapcar '(lambda (dir)
			 (let ((filename (concat dir "/" file))
			       )
			   (if (file-exists-p (expand-file-name filename))
			       (expand-file-name filename)
			     (if (file-exists-p (expand-file-name (concat
								   filename
								   ".elc")))
				 (expand-file-name (concat filename ".elc"))
			       (if (file-exists-p (expand-file-name (concat
								     filename
								     ".el")))
				   (expand-file-name (concat filename ".el"))
				 nil
				 )))
			   ))
		      load-path))
  )

(defun which (file)
  (interactive "sFile:  ")
  (message (or (car (make-which-list file))
	       "No file found."))
  )

(defun show-loads (file)
  
  "Show all possible loadings for file FILE in a buffer"

  (interactive "sFile:  ")
  (let ((whiches (make-which-list file))
	(b (get-buffer-create (concat "*Load Files for " file "*")))
	)
      (if whiches
	  (progn
	    (set-buffer b)
	    (erase-buffer)
	    (mapcar '(lambda (string)
		       (goto-char (point-max))
		       (insert string "\n")
		       )
		    whiches)
	    (goto-char (point-min))
	    (display-buffer b)
	    )
	(message "No files found."))
      ))
-- 

merlyn@intelob.intel.com (Randal L. Schwartz @ Stonehenge) (09/02/88)

In article <1140@titan.SW.MCC.COM>, janssen@titan (Bill Janssen) writes:
| [some nice lisp code]

Here's one that's a little shorter (and probably more robust) that I
wrote after seeing Bill's code.  Purists will want to change the
"'(lambda ...)"s to "(function (lambda ...))"s, but I'm not compiling
this one yet.  Note that this one properly handles the "nil" in the
load-path, and the NOSUFFIX flag of load.

(defun which-load (file &optional nosuffix)
  "Find out which FILE would be loaded with the current `load-path'.
Return a string representing the absolute path-name of the file that
would be loaded with a `load' command, or nil if no such file exists.
If optional NOSUFFIX is non-nil, don't try adding suffixes .elc or .el
to the specified name FILE (ala `load').  This function cannot test
the contents of the file for appropriateness to be loaded, but neither
does `load'."
  (catch 'answer
    (mapcar
     '(lambda (dir)
	(mapcar
	 '(lambda (suf)
	    (let ((try (expand-file-name (concat file suf) dir)))
	      (and (file-readable-p try)
		   (null (file-directory-p try))
		   (throw 'answer try))))
	 (if nosuffix '("") '(".elc" ".el" ""))))
     load-path)
    nil))

Yours for a better tomorrow,
-- 
Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095
on contract to BiiN Technical Publications (for now :-), Hillsboro, Oregon
<merlyn@intelob.intel.com> or ...!tektronix!inteloa[!intelob]!merlyn
Standard disclaimer: I *am* my employer!