comparison lisp/packages.el @ 267:966663fcf606 r20-5b32

Import from CVS: tag r20-5b32
author cvs
date Mon, 13 Aug 2007 10:26:29 +0200
parents 405dd6d1825b
children b2472a1930f2
comparison
equal deleted inserted replaced
266:18d185df8c54 267:966663fcf606
46 ;; `cus-start.el'. 46 ;; `cus-start.el'.
47 47
48 ;; Because of all this, make sure that the stuff you put here really 48 ;; Because of all this, make sure that the stuff you put here really
49 ;; belongs here. 49 ;; belongs here.
50 50
51 ;; This file requires find-paths.el.
51 52
52 ;;; Code: 53 ;;; Code:
53 54
54 ;;; Package versioning 55 ;;; Package versioning
55 56
56 (defvar packages-package-list nil 57 (defvar packages-package-list nil
57 "database of loaded packages and version numbers") 58 "database of loaded packages and version numbers")
59
60 (defvar early-packages nil
61 "Packages early in the load path.")
62
63 (defvar early-package-load-path nil
64 "Load path for packages early in the load path.")
65
66 (defvar early-packages nil
67 "Packages late in the load path.")
68
69 (defvar late-package-load-path nil
70 "Load path for packages late in the load path.")
58 71
59 (defun package-get-key-1 (info key) 72 (defun package-get-key-1 (info key)
60 "Locate keyword `key' in list." 73 "Locate keyword `key' in list."
61 (cond ((null info) 74 (cond ((null info)
62 nil) 75 nil)
247 "Reload new or updated dumped lisp files (with exceptions). 260 "Reload new or updated dumped lisp files (with exceptions).
248 This is an extremely dangerous function to call at any time." 261 This is an extremely dangerous function to call at any time."
249 ;; Nothing for the moment 262 ;; Nothing for the moment
250 nil) 263 nil)
251 264
252 ;; The following function is called from temacs
253 (defun packages-find-packages-1 (package path-only append-p user-package)
254 "Search the supplied directory for associated directories.
255 The top level is assumed to look like:
256 info/ Contain texinfo files for lisp installed in this hierarchy
257 etc/ Contain data files for lisp installled in this hierarchy
258 lisp/ Contain directories which either have straight lisp code
259 or are self-contained packages of their own.
260
261 If the argument `append-p' is non-nil, the found directories will be
262 appended to the paths, otherwise, they will be prepended.
263
264 This is an internal function. Do not call it after startup."
265 ;; Info files
266 (if (and (null path-only) (file-directory-p (concat package "/info")))
267 (let ((dir (concat package "/info/")))
268 (if (not (member dir Info-default-directory-list))
269 (nconc Info-default-directory-list (list dir)))))
270 ;; Data files
271 (if (and (null path-only) (file-directory-p (concat package "/etc")))
272 (setq data-directory-list
273 (if append-p
274 (append data-directory-list (list (concat package "/etc/")))
275 (cons (concat package "/etc/") data-directory-list))))
276 ;; Lisp files
277 (if (file-directory-p (concat package "/lisp"))
278 (progn
279 ; (print (concat "DIR: "
280 ; (if user-package "[USER]" "")
281 ; package
282 ; "/lisp/"))
283 (setq load-path
284 (if append-p
285 (append load-path (list (concat package "/lisp/")))
286 (cons (concat package "/lisp/") load-path)))
287
288 ;; Locate and process a dumped-lisp.el file if it exists
289 (if (and (running-temacs-p)
290 (file-exists-p (concat package "/lisp/dumped-lisp.el")))
291 (let (package-lisp)
292 (let (preloaded-file-list)
293 (load (concat package "/lisp/dumped-lisp.el")))
294 (if package-lisp
295 (progn
296 (if (boundp 'preloaded-file-list)
297 (setq preloaded-file-list
298 (append preloaded-file-list package-lisp)))
299 (if (fboundp 'load-gc)
300 (setq dumped-lisp-packages
301 (append dumped-lisp-packages package-lisp)))))))
302
303 (if user-package
304 (condition-case error
305 (load (concat package "/lisp/"
306 (file-name-sans-extension autoload-file-name))
307 t)
308 (error
309 (warn (format "Autoload error in: %s/lisp/:\n\t%s"
310 package
311 (with-output-to-string
312 (display-error error nil)))))))
313 (let ((dirs (directory-files (concat package "/lisp/")
314 t "^[^-.]" nil 'dirs-only))
315 dir)
316 (while dirs
317 (setq dir (car dirs))
318 ; (print (concat "DIR: " dir "/"))
319 (setq load-path
320 (if append-p
321 (append load-path (list (concat dir "/")))
322 (cons (concat dir "/") load-path)))
323
324 ;; Locate and process a dumped-lisp.el file if it exists
325 (if (and (running-temacs-p)
326 (file-exists-p (concat dir "/dumped-lisp.el")))
327 (let (package-lisp)
328 (let (preloaded-file-list)
329 (load (concat dir "/dumped-lisp.el")))
330 (if package-lisp
331 (progn
332 (if (boundp 'preloaded-file-list)
333 (setq preloaded-file-list
334 (append preloaded-file-list package-lisp)))
335 (if (fboundp 'load-gc)
336 (setq dumped-lisp-packages
337 (append dumped-lisp-packages
338 package-lisp)))))))
339
340 (if user-package
341 (condition-case error
342 (progn
343 ; (print
344 ; (concat dir "/"
345 ; (file-name-sans-extension autoload-file-name)))
346 (load
347 (concat dir "/"
348 (file-name-sans-extension autoload-file-name))
349 t))
350 (error
351 (warn (format "Autoload error in: %s/:\n\t%s"
352 dir
353 (with-output-to-string
354 (display-error error nil)))))))
355 (packages-find-packages-1 dir path-only append-p user-package)
356 (setq dirs (cdr dirs)))))))
357
358 ;; The following function is called from temacs
359 (defun packages-find-packages-2 (path path-only append-p suppress-user)
360 "Search the supplied path for associated directories.
361 If the argument `append-p' is non-nil, the found directories will be
362 appended to the paths, otherwise, they will be prepended.
363
364 This is an internal function. Do not call it after startup."
365 (let (dir)
366 (while path
367 (setq dir (car path))
368 ;; (prin1 (concat "Find: " (expand-file-name dir) "\n"))
369 (if (null (and (or suppress-user inhibit-package-init)
370 (string-match "^~" dir)))
371 (progn
372 ;; (print dir)
373 (packages-find-packages-1 (expand-file-name dir)
374 path-only
375 append-p
376 (string-match "^~" dir))))
377 (setq path (cdr path)))))
378
379 ;; The following function is called from temacs
380 (defun packages-find-packages (pkg-path path-only &optional suppress-user)
381 "Search the supplied path for additional info/etc/lisp directories.
382 Lisp directories if configured prior to build time will have equivalent
383 status as bundled packages.
384 If the argument `path-only' is non-nil, only the `load-path' will be set,
385 otherwise data directories and info directories will be added.
386 If the optional argument `suppress-user' is non-nil, package directories
387 rooted in a user login directory (like ~/.xemacs) will not be searched.
388 This is used at dump time to suppress the builder's local environment."
389 (let ((prefix-path nil))
390 (while (and pkg-path (car pkg-path))
391 (setq prefix-path (cons (car pkg-path) prefix-path)
392 pkg-path (cdr pkg-path)))
393 (packages-find-packages-2 (cdr pkg-path) path-only t suppress-user)
394 (packages-find-packages-2 prefix-path path-only nil suppress-user)))
395
396
397 ;; Data-directory is really a list now. Provide something to search it for 265 ;; Data-directory is really a list now. Provide something to search it for
398 ;; directories. 266 ;; directories.
399 267
400 (defun locate-data-directory (name &optional dir-list) 268 (defun locate-data-directory (name &optional dir-list)
401 "Locate a directory in a search path DIR-LIST (a list of directories). 269 "Locate a directory in a search path DIR-LIST (a list of directories).
420 This function is basically a wrapper over `locate-file'." 288 This function is basically a wrapper over `locate-file'."
421 (unless dir-list 289 (unless dir-list
422 (setq dir-list data-directory-list)) 290 (setq dir-list data-directory-list))
423 (locate-file name dir-list)) 291 (locate-file name dir-list))
424 292
425 ;; If we are being loaded as part of being dumped, bootstrap the rest of the 293 ;; Path setup
426 ;; load-path for loaddefs. 294
427 (if (fboundp 'load-gc) 295 (defun packages-find-package-path (roots)
428 (packages-find-packages package-path t t)) 296 "Construct the package path underneath installation roots ROOTS."
297 (let ((envvar-value (getenv "EMACSPACKAGEPATH")))
298 (if envvar-value
299 (decode-path-internal envvar-value)
300 (let ((site-base-directory (paths-find-site-directory roots "packages"))
301 (version-base-directory (paths-find-version-directory roots "packages")))
302 (if (or site-base-directory version-base-directory)
303 (let ((site-mule-directory
304 (and (featurep 'mule)
305 (paths-find-site-directory roots
306 "mule-packages")))
307 (version-mule-directory
308 (and (featurep 'mule)
309 (paths-find-version-directory roots
310 "mule-packages"))))
311 (append '("~/.xemacs/")
312 '(nil)
313 (and version-mule-directory
314 (null (string-equal version-mule-directory
315 site-mule-directory))
316 (list version-mule-directory))
317 (and site-mule-directory
318 (list site-mule-directory))
319 (and version-base-directory
320 (null (string-equal version-base-directory
321 site-base-directory))
322 (list version-base-directory))
323 (and site-base-directory
324 (list site-base-directory))))
325 configure-package-path)))))
326
327 (defvar packages-special-bases '("etc" "info" "lisp" "lib-src" "bin")
328 "Special subdirectories of packages.")
329
330 (defun packages-find-packages-in-directories (directories)
331 "Find all packages underneath directories in DIRECTORIES."
332 (paths-find-recursive-path directories
333 (append paths-version-control-bases
334 packages-special-bases)))
335
336 (defun packages-split-path (path)
337 "Split PATH at NIL, return pair with two components.
338 The second component is shared with PATH."
339 (let ((reverse-early '()))
340 (while (and path (null (null (car path))))
341 (setq reverse-early (cons (car path) reverse-early))
342 (setq path (cdr path)))
343 (if (null path)
344 (cons nil path)
345 (cons (reverse reverse-early) (cdr path)))))
346
347 (defun packages-find-packages (package-path &optional inhibit)
348 "Search for all packages in PACKAGE-PATH.
349 PACKAGE-PATH may distinguish (by NIL-separation) between early
350 and late packages.
351 If INHIBIT is non-NIL, return empty paths.
352 This returns (CONS EARLY-PACKAGES LATE-PACKAGES)."
353 (if inhibit
354 (cons '() '())
355 (let* ((stuff (packages-split-path package-path))
356 (early (car stuff))
357 (late (cdr stuff)))
358 (cons (packages-find-packages-in-directories early)
359 (packages-find-packages-in-directories late)))))
360
361 (defun packages-find-package-library-path (packages suffixes)
362 "Construct a path into a component of the packages hierarchy.
363 PACKAGES is a list of package directories.
364 SUFFIXES is a list of names of package subdirectories to look for."
365 (let ((directories
366 (apply
367 #'append
368 (mapcar #'(lambda (package)
369 (mapcar #'(lambda (suffix)
370 (concat package suffix))
371 suffixes))
372 packages))))
373 (paths-directories-which-exist directories)))
374
375 (defun packages-find-package-load-path (packages)
376 "Construct the load-path component for packages.
377 PACKAGES is a list of package directories."
378 (paths-find-recursive-load-path
379 (packages-find-package-library-path packages '("lisp/"))))
380
381 (defun packages-find-package-exec-path (packages)
382 (packages-find-package-library-path packages
383 (list (concat "bin/" system-configuration "/")
384 "lib-src/")))
385
386 (defun packages-find-package-info-path (packages)
387 (packages-find-package-library-path packages '("info/")))
388
389 (defun packages-find-package-data-path (packages)
390 (packages-find-package-library-path packages '("etc/")))
391
392 ;; Loading package initialization files
393
394 (defun packages-load-package-lisps (package-load-path base)
395 "Load all Lisp files of a certain name along a load path.
396 BASE is the base name of the files."
397 (mapc #'(lambda (dir)
398 (let ((file-name (expand-file-name base dir)))
399 (if (file-exists-p file-name)
400 (condition-case error
401 (load file-name)
402 (error
403 (warn (format "Autoload error in: %s:\n\t%s"
404 file-name
405 (with-output-to-string
406 (display-error error nil)))))))))
407 package-load-path))
408
409 (defun packages-load-package-auto-autoloads (package-load-path)
410 "Load auto-autoload files along a load path."
411 (packages-load-package-lisps package-load-path
412 (file-name-sans-extension autoload-file-name)))
413
414 (defun packages-handle-package-dumped-lisps (handle package-load-path)
415 "Load dumped-lisp.el files along a load path.
416 Call HANDLE on each file off definitions of PACKAGE-LISP there."
417 (mapc #'(lambda (dir)
418 (let ((file-name (expand-file-name "dumped-lisp.el" dir)))
419 (if (file-exists-p file-name)
420 (let (package-lisp
421 ;; 20.4 packages could set this
422 preloaded-file-list)
423 (load file-name)
424 ;; dumped-lisp.el could have set this ...
425 (if package-lisp
426 (mapc #'(lambda (base)
427 (funcall handle (expand-file-name base dir)))
428 package-lisp))))))
429 package-load-path))
430
431 (defun packages-load-package-dumped-lisps (package-load-path)
432 "Load dumped-lisp.el files along a load path.
433 Also load files off PACKAGE-LISP definitions there"
434 (packages-handle-package-dumped-lisps #'load package-load-path))
435
436 (defun packages-collect-package-dumped-lisps (package-load-path)
437 "Load dumped-lisp.el files along a load path.
438 Return list of files off PACKAGE-LISP definitions there"
439 (let ((*files* '()))
440 (packages-handle-package-dumped-lisps
441 #'(lambda (file)
442 (setq *files* (cons (file-name-nondirectory file)
443 *files*)))
444 package-load-path)
445 (reverse *files*)))
429 446
430 (provide 'packages) 447 (provide 'packages)
431 448
432 ;;; packages.el ends here 449 ;;; packages.el ends here