]> code.delx.au - gnu-emacs-elpa/blob - packages/load-relative/load-relative.el
Fix some quoting problems in doc strings
[gnu-emacs-elpa] / packages / load-relative / load-relative.el
1 ;;; load-relative.el --- relative file load (within a multi-file Emacs package)
2
3 ;; Author: Rocky Bernstein <rocky@gnu.org>
4 ;; Version: 1.2
5 ;; Keywords: internal
6 ;; URL: http://github.com/rocky/emacs-load-relative
7 ;; Compatibility: GNU Emacs 23.x
8
9 ;; Copyright (C) 2015 Free Software Foundation, Inc
10
11 ;; This program is free software: you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License as
13 ;; published by the Free Software Foundation, either version 3 of the
14 ;; License, or (at your option) any later version.
15
16 ;; This program is distributed in the hope that it will be useful, but
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;; General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with this program. If not, see
23 ;; <http://www.gnu.org/licenses/>.
24
25 ;;; Commentary:
26
27 ;; Here we provide functions which facilitate writing multi-file Emacs
28 ;; packages and facilitate running from the source tree without having
29 ;; to "install" code or fiddle with evil `load-path'. See
30 ;; https://github.com/rocky/emacs-load-relative/wiki/NYC-Lisp-talk for
31 ;; the the rationale behind this.
32 ;;
33 ;; The functions we add are relative versions of `load', `require' and
34 ;; `find-file-no-select' and versions which take list arguments. We also add a
35 ;; `__FILE__' function and a `provide-me' macro.
36
37 ;; The latest version of this code is at:
38 ;; http://github.com/rocky/emacs-load-relative/
39
40 ;; `__FILE__' returns the file name that that the calling program is
41 ;; running. If you are `eval''ing a buffer then the file name of that
42 ;; buffer is used. The name was selected to be analogous to the name
43 ;; used in C, Perl, Python, and Ruby.
44
45 ;; `load-relative' loads an Emacs Lisp file relative to another
46 ;; (presumably currently running) Emacs Lisp file. For example suppose
47 ;; you have Emacs Lisp files "foo.el" and "bar.el" in the same
48 ;; directory. To load "bar.el" from inside Emacs Lisp file "foo.el":
49 ;;
50 ;; (require 'load-relative)
51 ;; (load-relative "baz")
52 ;;
53 ;; The above `load-relative' line could above have also been written as:
54 ;;
55 ;; (load-relative "./baz")
56 ;; or:
57 ;; (load-relative "baz.el") # if you want to exclude any byte-compiled files
58 ;;
59 ;; Use `require-relative' if you want to `require' the file instead of
60 ;; `load'ing it:
61 ;;
62 ;; (require-relative "baz")
63 ;;
64 ;; or:
65 ;;
66 ;; (require-relative "./baz")
67 ;;
68 ;; The above not only does a `require' on 'baz', but makes sure you
69 ;; get that from the same file as you would have if you had issued
70 ;; `load_relative'.
71 ;;
72 ;; Use `require-relative-list' when you have a list of files you want
73 ;; to `require'. To `require-relative' them all in one shot:
74 ;;
75 ;; (require-relative-list '("dbgr-init" "dbgr-fringe"))
76 ;;
77 ;; The macro `provide-me' saves you the trouble of adding a
78 ;; symbol after `provide' using the file basename (without directory
79 ;; or file extension) as the name of the thing you want to
80 ;; provide.
81 ;;
82 ;; Using this constrains the `provide' name to be the same as
83 ;; the filename, but I consider that a good thing.
84 ;;
85 ;; The function `find-file-noselect-relative' provides a way of accessing
86 ;; resources which are located relative to the currently running Emacs Lisp
87 ;; file. This is probably most useful when running Emacs as a scripting engine
88 ;; for batch processing or with tests cases. For example, this form will find
89 ;; the README file for this package.
90 ;;
91 ;; (find-file-noselect-relative "README.md")
92 ;;
93 ;; `find-file-noselect-relative' also takes wildcards, as does it's
94 ;; non-relative namesake.
95 ;;
96 ;; The macro `with-relative-file' runs in a buffer with the contents of the
97 ;; given relative file.
98 ;;
99 ;; (with-relative-file "README.md"
100 ;; (buffer-substring))
101 ;;
102 ;; This is easier if you care about the contents of the file, rather than
103 ;; a buffer.
104
105
106 ;;; Code:
107
108 ;;;###autoload
109 (defun __FILE__ (&optional symbol)
110 "Return the string name of file/buffer that is currently begin executed.
111
112 The first approach for getting this information is perhaps the
113 most pervasive and reliable. But it the most low-level and not
114 part of a public API, so it might change in future
115 implementations. This method uses the name that is recorded by
116 readevalloop of `lread.c' as the car of variable
117 `current-load-list'.
118
119 Failing that, we use `load-file-name' which should work in some
120 subset of the same places that the first method works. However
121 `load-file-name' will be nil for code that is eval'd. To cover
122 those cases, we try `buffer-file-name' which is initially
123 correct, for eval'd code, but will change and may be wrong if the
124 code sets or switches buffers after the initial execution.
125
126 As a last resort, you can pass in SYMBOL which should be some
127 symbol that has been previously defined if none of the above
128 methods work we will use the file-name value find via
129 `symbol-file'."
130 ;; Not used right now:
131 ;; Failing the above the next approach we try is to use the value of
132 ;; $# - 'the name of this file as a string'. Although it doesn't
133 ;; work for eval-like things, it has the advantage that this value
134 ;; persists after loading or evaluating a file. So it would be
135 ;; suitable if __FILE__ were called from inside a function.
136
137
138 (cond
139 ;; lread.c's readevalloop sets (car current-load-list)
140 ;; via macro LOADHIST_ATTACH of lisp.h. At least in Emacs
141 ;; 23.0.91 and this code goes back to '93.
142 ((stringp (car-safe current-load-list)) (car current-load-list))
143
144 ;; load-like things. 'relative-file-expand' tests in
145 ;; test/test-load.el indicates we should put this ahead of
146 ;; $#.
147 (load-file-name)
148
149 ;; Pick up "name of this file as a string" which is set on
150 ;; reading and persists. In contrast, load-file-name is set only
151 ;; inside eval. As such, it won't work when not in the middle of
152 ;; loading.
153 ;; (#$)
154
155 ;; eval-like things
156 ((buffer-file-name))
157
158 ;; When byte compiling. FIXME: use a more thorough precondition like
159 ;; byte-compile-file is somehwere in the backtrace or that
160 ;; bytecomp-filename comes from that routine?
161 ;; FIXME: `bytecomp-filename' doesn't exist any more (since Emacs-24.1).
162 ((boundp 'bytecomp-filename) bytecomp-filename)
163
164 (t (symbol-file symbol)) ;; last resort
165 ))
166
167 (defun autoload-relative (function-or-list
168 file &optional docstring interactive type
169 symbol)
170 "Autoload an Emacs Lisp file relative to Emacs Lisp code that is in
171 the process of being loaded or eval'd.
172
173
174 Define FUNCTION to autoload from FILE. FUNCTION is a symbol.
175
176 FILE is a string to pass to `load'.
177
178 DOCSTRING is documentation for the function.
179
180 INTERACATIVE if non-nil says function can be called
181 interactively.
182
183 TYPE indicates the type of the object: nil or omitted says
184 function is a function, `keymap' says function is really a
185 keymap, and `macro' or t says function is really a macro. Third
186 through fifth args give info about the real definition. They
187 default to nil. If function is already defined other than as an
188 autoload, this does nothing and returns nil.
189
190 SYMBOL is the location of of the file of where that was
191 defined (as given by `symbol-file' is used if other methods of
192 finding __FILE__ don't work."
193
194 (if (listp function-or-list)
195 (mapcar (lambda(function)
196 (autoload function-or-list
197 (relative-expand-file-name file symbol)
198 docstring interactive type))
199 file)
200 (autoload function-or-list (relative-expand-file-name file symbol)
201 docstring interactive type))
202 )
203
204 ;;;###autoload
205 (defun find-file-noselect-relative (filename &optional nowarn rawfile wildcards)
206 "Read relative FILENAME into a buffer and return the buffer.
207 If a buffer exists visiting FILENAME, return that one, but
208 verify that the file has not changed since visited or saved.
209 The buffer is not selected, just returned to the caller.
210 Optional second arg NOWARN non-nil means suppress any warning messages.
211 Optional third arg RAWFILE non-nil means the file is read literally.
212 Optional fourth arg WILDCARDS non-nil means do wildcard processing
213 and visit all the matching files. When wildcards are actually
214 used and expanded, return a list of buffers that are visiting
215 the various files."
216 (find-file-noselect (relative-expand-file-name filename)
217 nowarn rawfile wildcards))
218
219 ;;;###autoload
220 (defmacro with-relative-file (file &rest body)
221 "Read the relative FILE into a temporary buffer and evaluate BODY
222 in this buffer."
223 (declare (indent 1) (debug t))
224 `(with-temp-buffer
225 (insert-file-contents
226 (relative-expand-file-name
227 ,file))
228 ,@body))
229
230 ;;;###autoload
231 (defun load-relative (file-or-list &optional symbol)
232 "Load an Emacs Lisp file relative to Emacs Lisp code that is in
233 the process of being loaded or eval'd.
234
235 FILE-OR-LIST is either a string or a list of strings containing
236 files that you want to loaded. If SYMBOL is given, the location of
237 of the file of where that was defined (as given by `symbol-file' is used
238 if other methods of finding __FILE__ don't work."
239
240 (if (listp file-or-list)
241 (mapcar (lambda(relative-file)
242 (load (relative-expand-file-name relative-file symbol)))
243 file-or-list)
244 (load (relative-expand-file-name file-or-list symbol)))
245 )
246
247 (defun relative-expand-file-name(relative-file &optional opt-file)
248 "Expand RELATIVE-FILE relative to the Emacs Lisp code that is in
249 the process of being loaded or eval'd.
250
251 WARNING: it is best to run this function before any
252 buffer-setting or buffer changing operations."
253 (let ((file (or opt-file (__FILE__) default-directory))
254 (prefix))
255 (unless file
256 ;; FIXME: Since default-directory should basically never be nil, this
257 ;; should basically never trigger!
258 (error "Can't expand __FILE__ here and no file name given"))
259 (setq prefix (file-name-directory file))
260 (expand-file-name (concat prefix relative-file))))
261
262 ;;;###autoload
263 (defun require-relative (relative-file &optional opt-file opt-prefix)
264 "Run `require' on an Emacs Lisp file relative to the Emacs Lisp code
265 that is in the process of being loaded or eval'd. The symbol used in require
266 is the base file name (without directory or file extension) treated as a
267 symbol.
268
269 WARNING: it is best to to run this function before any
270 buffer-setting or buffer changing operations."
271 (let ((require-string-name
272 (concat opt-prefix (file-name-sans-extension
273 (file-name-nondirectory relative-file)))))
274 (require (intern require-string-name)
275 (relative-expand-file-name relative-file opt-file))))
276
277 ;;;###autoload
278 (defmacro require-relative-list (list &optional opt-prefix)
279 "Run `require-relative' on each name in LIST which should be a list of
280 strings, each string being the relative name of file you want to run."
281 `(progn
282 (eval-when-compile
283 (require 'cl
284 (dolist (rel-file ,list)
285 (require-relative rel-file (__FILE__) ,opt-prefix))))
286 (dolist (rel-file ,list)
287 (require-relative rel-file (__FILE__) ,opt-prefix))))
288
289 ;;;###autoload
290 (defmacro provide-me ( &optional prefix )
291 "Call `provide' with the feature's symbol name made from
292 source-code's file basename sans extension. For example if you
293 write (provide-me) inside file ~/lisp/foo.el, this is the same as
294 writing: (provide \\='foo).
295
296 With a prefix, that prefix is prepended to the `provide' So in
297 the previous example, if you write (provide-me \"bar-\") this is the
298 same as writing (provide \\='bar-foo)."
299 `(provide (intern (concat ,prefix (file-name-sans-extension
300 (file-name-nondirectory (__FILE__)))))))
301
302 (provide-me)
303
304 ;;; load-relative.el ends here