]> code.delx.au - gnu-emacs-elpa/blob - packages/load-dir/load-dir.el
Merge commit '0cda39255827f283e7578cd469ae42daad9556a2' from js2-mode
[gnu-emacs-elpa] / packages / load-dir / load-dir.el
1 ;;; load-dir.el --- Load all Emacs Lisp files in a given directory
2
3 ;; Copyright (C) 2011 Free Software Foundation, Inc
4
5 ;; Authors: Teodor Zlatanov <tzz@lifelogs.com>,
6 ;; Ben Key <bkey76@gmail.com>
7 ;; With-Help-From: Evans Winner <ego111@gmail.com>, PJ Weisberg <pj@irregularexpressions.net>
8 ;; Version: 0.0.3
9 ;; Keywords: lisp, files, convenience
10
11 ;; This file is part of GNU Emacs.
12
13 ;; GNU Emacs is free software: you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by
15 ;; the Free Software Foundation, either version 3 of the License, or
16 ;; (at your option) any later version.
17
18 ;; GNU Emacs is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;; GNU General Public License for more details.
22
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25
26 ;;; Commentary:
27
28 ;; This package provides a way to load all Emacs Lisp snippets (they
29 ;; don't have to be libraries) in a directory on startup or when Emacs is
30 ;; already running. It won't reload snippets unless the user requests
31 ;; it, so for instance adding a lambda to a hook is usually safe.
32 ;;
33 ;; You can specify ~/.emacs.d/load.d, a single directory, or a list of
34 ;; directories. The file search can be recursive. See the
35 ;; customizable variable `load-dirs' for details.
36 ;;
37 ;; The intent of ~/.emacs.d/load.d is to give package installers like
38 ;; el-get.el (see https://github.com/dimitri/el-get) and other tools a
39 ;; way to easily bootstrap themselves without necessarily modifying
40 ;; your .emacs or custom files directly.
41
42 ;;; Code:
43
44 (eval-when-compile (require 'cl))
45
46 (defgroup load-dir nil
47 "Automatically load all Emacs Lisp files in given directories."
48 :group 'initialization)
49
50 (defcustom load-dir-debug t
51 "Debugging messages toggle, default to t."
52 :group 'load-dir
53 :type 'boolean)
54
55 (defcustom load-dir-recursive nil
56 "Whether subdirectories should be loaded too."
57 :group 'load-dir
58 :type 'boolean)
59
60 (defcustom load-dir-ignore-errors nil
61 "Whether errors in the loaded files should be ignored."
62 :group 'load-dir
63 :type 'boolean)
64
65 (defcustom load-dirs nil
66 "This variable allows you to define which directories should be loaded.
67
68 If nil, no directories are loaded. This is the default behavior.
69 If t, only files in ~/.emacs.d/load.d will be loaded.
70 If a single directory name, only files in that directory will be loaded.
71 If a list of directory names, all files found in all the
72 directories will be loaded."
73 :group 'load-dir
74 :tag "What directories to load"
75 :type '(choice (const :tag "Load all from ~/.emacs.d/load.d" t)
76 (const :tag "Don't load anything" nil)
77 directory
78 (repeat :tag "Directories" directory)))
79
80 ;;;###autoload
81 (defun load-dirs ()
82 "Load all Emacs Lisp files in `load-dirs'.
83 Will not load a file twice (use `load-dir-reload' for that).
84 Recurses into subdirectories if `load-dir-recursive' is t."
85 (interactive)
86 ;; avoid the case where users inadvertently set `load-dirs' to a string
87 (mapc 'load-dir-one (cond
88 ((eq load-dirs t)
89 (list (expand-file-name "~/.emacs.d/load.d")))
90 ((stringp load-dirs)
91 (list load-dirs))
92 (t load-dirs))))
93
94 (defvar load-dir-loaded nil
95 "List of already loaded files.")
96
97 ;;;###autoload
98 (defun load-dirs-reload ()
99 "Load all Emacs Lisp files in `load-dirs'.
100 Clears the list of loaded files and just calls `load-dir-load'."
101 (interactive)
102 (setq load-dir-loaded nil)
103 (load-dirs))
104
105 (defun load-dir-one (dir)
106 "Load all Emacs Lisp files in DIR.
107 Recurses into subdirectories if `load-dir-recursive' is t."
108 (load-dir-debug "Loading Emacs Lisp code from %s" dir)
109 (let ((suffixes (get-load-suffixes)))
110 (dolist (f (and (file-exists-p dir)
111 (file-directory-p dir)
112 (directory-files dir t)))
113 (when (and (not (file-directory-p f))
114 (member (file-name-extension f t) suffixes))
115 (setq f (file-name-sans-extension f))
116 (if (member f load-dir-loaded)
117 (load-dir-debug "Skipping %s, it's already loaded." f)
118 (if load-dir-ignore-errors
119 (with-demoted-errors (load f))
120 (load f))
121 (add-to-list 'load-dir-loaded f))))
122
123 (when load-dir-recursive
124 (dolist (f (directory-files dir t directory-files-no-dot-files-regexp))
125 (when (file-directory-p f)
126 (load-dir-one f))))))
127
128 (defun load-dir-debug (&rest args)
129 "Print a debug message like `message' if `load-dir-debug' is set."
130 (when load-dir-debug
131 (apply 'message args)))
132
133 ;;;###autoload
134 (add-hook 'after-init-hook 'load-dirs)
135
136 (provide 'load-dir)
137 ;;; load-dir.el ends here