evaluation time changes
[bpt/emacs.git] / lisp / emacs-lisp / autoload.el
CommitLineData
500fcedc 1;; autoload.el --- maintain autoloads in loaddefs.el -*- lexical-binding: t -*-
c0274f38 2
ba318903 3;; Copyright (C) 1991-1997, 2001-2014 Free Software Foundation, Inc.
b578f267 4
5762abec 5;; Author: Roland McGrath <roland@gnu.org>
e9571d2a 6;; Keywords: maint
bd78fa1d 7;; Package: emacs
e5167999 8
b578f267
EN
9;; This file is part of GNU Emacs.
10
d6cba7ae 11;; GNU Emacs is free software: you can redistribute it and/or modify
b578f267 12;; it under the terms of the GNU General Public License as published by
d6cba7ae
GM
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
b578f267
EN
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
d6cba7ae 22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
0231f2dc 23
07b3798c 24;;; Commentary:
e41b2db1 25
00ee57f3 26;; This code helps GNU Emacs maintainers keep the loaddefs.el file up to
e41b2db1
ER
27;; date. It interprets magic cookies of the form ";;;###autoload" in
28;; lisp source files in various useful ways. To learn more, read the
29;; source; if you're going to use this, you'd better be able to.
30
e5167999
ER
31;;; Code:
32
b0daab9a 33(require 'lisp-mode) ;for `doc-string-elt' properties.
66bd25ab 34(require 'lisp-mnt)
890df022 35(require 'help-fns) ;for help-add-fundoc-usage.
f80efb86 36(eval-when-compile (require 'cl-lib))
b0daab9a 37
9ed7c8cb
CY
38(defvar generated-autoload-file nil
39 "File into which to write autoload definitions.
b7d22a83
CY
40A Lisp file can set this in its local variables section to make
41its autoloads go somewhere else.
42
43If this is a relative file name, the directory is determined as
44follows:
45 - If a Lisp file defined `generated-autoload-file' as a
46 file-local variable, use its containing directory.
47 - Otherwise use the \"lisp\" subdirectory of `source-directory'.
48
49The autoload file is assumed to contain a trailer starting with a
50FormFeed character.")
a25beddb 51;;;###autoload
3b979520 52(put 'generated-autoload-file 'safe-local-variable 'stringp)
0ceb5fe0 53
15120dec
CY
54(defvar generated-autoload-load-name nil
55 "Load name for `autoload' statements generated from autoload cookies.
0060ac73
GM
56If nil, this defaults to the file name, sans extension.
57Typically, you need to set this when the directory containing the file
58is not in `load-path'.
59This also affects the generated cus-load.el file.")
15120dec
CY
60;;;###autoload
61(put 'generated-autoload-load-name 'safe-local-variable 'stringp)
62
3b979520
SM
63;; This feels like it should be a defconst, but MH-E sets it to
64;; ";;;###mh-autoload" for the autoloads that are to go into mh-loaddefs.el.
65(defvar generate-autoload-cookie ";;;###autoload"
0ceb5fe0
RS
66 "Magic comment indicating the following form should be autoloaded.
67Used by \\[update-file-autoloads]. This string should be
68meaningless to Lisp (e.g., a comment).
69
70This string is used:
71
3b979520 72\;;;###autoload
0ceb5fe0
RS
73\(defun function-to-be-autoloaded () ...)
74
75If this string appears alone on a line, the following form will be
76read and an autoload made for it. If there is further text on the line,
77that text will be copied verbatim to `generated-autoload-file'.")
78
a0436952
GM
79(defvar autoload-excludes nil
80 "If non-nil, list of absolute file names not to scan for autoloads.")
81
0ceb5fe0 82(defconst generate-autoload-section-header "\f\n;;;### "
2336b6a9 83 "String that marks the form at the start of a new file's autoload section.")
0ceb5fe0
RS
84
85(defconst generate-autoload-section-trailer "\n;;;***\n"
86 "String which indicates the end of the section of autoloads for a file.")
87
2336b6a9
KH
88(defconst generate-autoload-section-continuation ";;;;;; "
89 "String to add on each continuation of the section header form.")
90
1fad2b12
SM
91(defvar autoload-modified-buffers) ;Dynamically scoped var.
92
500fcedc 93(defun make-autoload (form file &optional expansion)
ceaa3695 94 "Turn FORM into an autoload or defvar for source file FILE.
e8139c11 95Returns nil if FORM is not a special autoload form (i.e. a function definition
500fcedc
SM
96or macro definition or a defcustom).
97If EXPANSION is non-nil, we're processing the macro expansion of an
98expression, in which case we want to handle forms differently."
e8139c11
SM
99 (let ((car (car-safe form)) expand)
100 (cond
500fcedc
SM
101 ((and expansion (eq car 'defalias))
102 (pcase-let*
103 ((`(,_ ,_ ,arg . ,rest) form)
104 ;; `type' is non-nil if it defines a macro.
105 ;; `fun' is the function part of `arg' (defaults to `arg').
106 ((or (and (or `(cons 'macro ,fun) `'(macro . ,fun)) (let type t))
107 (and (let fun arg) (let type nil)))
108 arg)
109 ;; `lam' is the lambda expression in `fun' (or nil if not
110 ;; recognized).
111 (lam (if (memq (car-safe fun) '(quote function)) (cadr fun)))
112 ;; `args' is the list of arguments (or t if not recognized).
113 ;; `body' is the body of `lam' (or t if not recognized).
114 ((or `(lambda ,args . ,body)
115 (and (let args t) (let body t)))
116 lam)
117 ;; Get the `doc' from `body' or `rest'.
118 (doc (cond ((stringp (car-safe body)) (car body))
119 ((stringp (car-safe rest)) (car rest))))
120 ;; Look for an interactive spec.
121 (interactive (pcase body
122 ((or `((interactive . ,_) . ,_)
123 `(,_ (interactive . ,_) . ,_)) t))))
124 ;; Add the usage form at the end where describe-function-1
125 ;; can recover it.
126 (when (listp args) (setq doc (help-add-fundoc-usage doc args)))
127 ;; (message "autoload of %S" (nth 1 form))
128 `(autoload ,(nth 1 form) ,file ,doc ,interactive ,type)))
129
130 ((and expansion (memq car '(progn prog1)))
131 (let ((end (memq :autoload-end form)))
132 (when end ;Cut-off anything after the :autoload-end marker.
133 (setq form (copy-sequence form))
134 (setcdr (memq :autoload-end form) nil))
135 (let ((exps (delq nil (mapcar (lambda (form)
136 (make-autoload form file expansion))
137 (cdr form)))))
138 (when exps (cons 'progn exps)))))
139
e8139c11 140 ;; For complex cases, try again on the macro-expansion.
1b39b493 141 ((and (memq car '(easy-mmode-define-global-mode define-global-minor-mode
500fcedc
SM
142 define-globalized-minor-mode defun defmacro
143 ;; FIXME: we'd want `defmacro*' here as well, so as
144 ;; to handle its `declare', but when autoload is run
145 ;; CL is not loaded so macroexpand doesn't know how
146 ;; to expand it!
e8139c11
SM
147 easy-mmode-define-minor-mode define-minor-mode))
148 (setq expand (let ((load-file-name file)) (macroexpand form)))
500fcedc
SM
149 (memq (car expand) '(progn prog1 defalias)))
150 (make-autoload expand file 'expansion)) ;Recurse on the expansion.
e8139c11
SM
151
152 ;; For special function-like operators, use the `autoload' function.
500fcedc 153 ((memq car '(define-skeleton define-derived-mode
c6a3142d
JL
154 define-compilation-mode define-generic-mode
155 easy-mmode-define-global-mode define-global-minor-mode
32324290 156 define-globalized-minor-mode
c6a3142d 157 easy-mmode-define-minor-mode define-minor-mode
a12ac9d7
SM
158 cl-defun defun* cl-defmacro defmacro*
159 define-overloadable-function))
13af0d10 160 (let* ((macrop (memq car '(defmacro cl-defmacro defmacro*)))
e8139c11 161 (name (nth 1 form))
f58e0fd5
SM
162 (args (pcase car
163 ((or `defun `defmacro
164 `defun* `defmacro* `cl-defun `cl-defmacro
165 `define-overloadable-function) (nth 2 form))
166 (`define-skeleton '(&optional str arg))
167 ((or `define-generic-mode `define-derived-mode
168 `define-compilation-mode) nil)
169 (_ t)))
7abaf5cc 170 (body (nthcdr (or (function-get car 'doc-string-elt) 3) form))
e8139c11 171 (doc (if (stringp (car body)) (pop body))))
500fcedc
SM
172 ;; Add the usage form at the end where describe-function-1
173 ;; can recover it.
174 (when (listp args) (setq doc (help-add-fundoc-usage doc args)))
175 ;; `define-generic-mode' quotes the name, so take care of that
7abaf5cc
SM
176 `(autoload ,(if (listp name) name (list 'quote name))
177 ,file ,doc
178 ,(or (and (memq car '(define-skeleton define-derived-mode
179 define-generic-mode
180 easy-mmode-define-global-mode
181 define-global-minor-mode
182 define-globalized-minor-mode
183 easy-mmode-define-minor-mode
184 define-minor-mode)) t)
185 (eq (car-safe (car body)) 'interactive))
186 ,(if macrop ''macro nil))))
e8139c11 187
15120dec
CY
188 ;; For defclass forms, use `eieio-defclass-autoload'.
189 ((eq car 'defclass)
190 (let ((name (nth 1 form))
191 (superclasses (nth 2 form))
192 (doc (nth 4 form)))
193 (list 'eieio-defclass-autoload (list 'quote name)
194 (list 'quote superclasses) file doc)))
195
d49298d9 196 ;; Convert defcustom to less space-consuming data.
e8139c11
SM
197 ((eq car 'defcustom)
198 (let ((varname (car-safe (cdr-safe form)))
199 (init (car-safe (cdr-safe (cdr-safe form))))
200 (doc (car-safe (cdr-safe (cdr-safe (cdr-safe form)))))
d49298d9
MR
201 ;; (rest (cdr-safe (cdr-safe (cdr-safe (cdr-safe form)))))
202 )
203 `(progn
204 (defvar ,varname ,init ,doc)
fb2dd970
SM
205 (custom-autoload ',varname ,file
206 ,(condition-case nil
207 (null (cadr (memq :set form)))
208 (error nil))))))
e8139c11 209
1bddeeed
SM
210 ((eq car 'defgroup)
211 ;; In Emacs this is normally handled separately by cus-dep.el, but for
212 ;; third party packages, it can be convenient to explicitly autoload
213 ;; a group.
214 (let ((groupname (nth 1 form)))
215 `(let ((loads (get ',groupname 'custom-loads)))
216 (if (member ',file loads) nil
217 (put ',groupname 'custom-loads (cons ',file loads))))))
218
500fcedc
SM
219 ;; When processing a macro expansion, any expression
220 ;; before a :autoload-end should be included. These are typically (put
221 ;; 'fun 'prop val) and things like that.
222 ((and expansion (consp form)) form)
223
e8139c11
SM
224 ;; nil here indicates that this is not a special autoload form.
225 (t nil))))
0231f2dc 226
890df022
SM
227;; Forms which have doc-strings which should be printed specially.
228;; A doc-string-elt property of ELT says that (nth ELT FORM) is
229;; the doc-string in FORM.
230;; Those properties are now set in lisp-mode.el.
fc89daee 231
9ed7c8cb
CY
232(defun autoload-find-generated-file ()
233 "Visit the autoload file for the current buffer, and return its buffer.
234If a buffer is visiting the desired autoload file, return it."
7aacaf15
GM
235 (let ((enable-local-variables :safe)
236 (enable-local-eval nil))
9ed7c8cb
CY
237 ;; We used to use `raw-text' to read this file, but this causes
238 ;; problems when the file contains non-ASCII characters.
239 (find-file-noselect
240 (autoload-ensure-default-file (autoload-generated-file)))))
241
3b979520
SM
242(defun autoload-generated-file ()
243 (expand-file-name generated-autoload-file
438d6bb6
SM
244 ;; File-local settings of generated-autoload-file should
245 ;; be interpreted relative to the file's location,
246 ;; of course.
247 (if (not (local-variable-p 'generated-autoload-file))
248 (expand-file-name "lisp" source-directory))))
0231f2dc 249
72c19d97 250
2336b6a9
KH
251(defun autoload-read-section-header ()
252 "Read a section header form.
253Since continuation lines have been marked as comments,
254we must copy the text of the form and remove those comment
255markers before we call `read'."
256 (save-match-data
257 (let ((beginning (point))
258 string)
259 (forward-line 1)
260 (while (looking-at generate-autoload-section-continuation)
261 (forward-line 1))
262 (setq string (buffer-substring beginning (point)))
263 (with-current-buffer (get-buffer-create " *autoload*")
264 (erase-buffer)
265 (insert string)
266 (goto-char (point-min))
267 (while (search-forward generate-autoload-section-continuation nil t)
268 (replace-match " "))
269 (goto-char (point-min))
270 (read (current-buffer))))))
271
ac644d50
JB
272(defvar autoload-print-form-outbuf nil
273 "Buffer which gets the output of `autoload-print-form'.")
4a3c5b3a 274
a8add29d 275(defun autoload-print-form (form)
4a3c5b3a
RS
276 "Print FORM such that `make-docfile' will find the docstrings.
277The variable `autoload-print-form-outbuf' specifies the buffer to
278put the output in."
a8add29d
SM
279 (cond
280 ;; If the form is a sequence, recurse.
281 ((eq (car form) 'progn) (mapcar 'autoload-print-form (cdr form)))
282 ;; Symbols at the toplevel are meaningless.
283 ((symbolp form) nil)
284 (t
7abaf5cc 285 (let ((doc-string-elt (function-get (car-safe form) 'doc-string-elt))
4a3c5b3a 286 (outbuf autoload-print-form-outbuf))
a8add29d
SM
287 (if (and doc-string-elt (stringp (nth doc-string-elt form)))
288 ;; We need to hack the printing because the
289 ;; doc-string must be printed specially for
290 ;; make-docfile (sigh).
291 (let* ((p (nthcdr (1- doc-string-elt) form))
292 (elt (cdr p)))
293 (setcdr p nil)
294 (princ "\n(" outbuf)
295 (let ((print-escape-newlines t)
9d8563ca 296 (print-quoted t)
a8add29d 297 (print-escape-nonascii t))
7dab57b6
RS
298 (dolist (elt form)
299 (prin1 elt outbuf)
300 (princ " " outbuf)))
a8add29d
SM
301 (princ "\"\\\n" outbuf)
302 (let ((begin (with-current-buffer outbuf (point))))
303 (princ (substring (prin1-to-string (car elt)) 1)
304 outbuf)
305 ;; Insert a backslash before each ( that
306 ;; appears at the beginning of a line in
307 ;; the doc string.
308 (with-current-buffer outbuf
309 (save-excursion
890df022 310 (while (re-search-backward "\n[[(]" begin t)
a8add29d
SM
311 (forward-char 1)
312 (insert "\\"))))
313 (if (null (cdr elt))
314 (princ ")" outbuf)
315 (princ " " outbuf)
316 (princ (substring (prin1-to-string (cdr elt)) 1)
317 outbuf))
318 (terpri outbuf)))
319 (let ((print-escape-newlines t)
9d8563ca 320 (print-quoted t)
a8add29d
SM
321 (print-escape-nonascii t))
322 (print form outbuf)))))))
323
4ad6a5e7 324(defun autoload-rubric (file &optional type feature)
a98f63d4
GM
325 "Return a string giving the appropriate autoload rubric for FILE.
326TYPE (default \"autoloads\") is a string stating the type of
4ad6a5e7
GM
327information contained in FILE. If FEATURE is non-nil, FILE
328will provide a feature. FEATURE may be a string naming the
c70815f1
GM
329feature, otherwise it will be based on FILE's name.
330
331At present, a feature is in fact always provided, but this should
332not be relied upon."
a98f63d4
GM
333 (let ((basename (file-name-nondirectory file)))
334 (concat ";;; " basename
335 " --- automatically extracted " (or type "autoloads") "\n"
336 ";;\n"
337 ";;; Code:\n\n"
338 "\f\n"
c70815f1 339 ;; This is used outside of autoload.el, eg cus-dep, finder.
0ad57dfd
CY
340 "(provide '"
341 (if (stringp feature)
342 feature
343 (file-name-sans-extension basename))
344 ")\n"
a98f63d4
GM
345 ";; Local Variables:\n"
346 ";; version-control: never\n"
347 ";; no-byte-compile: t\n"
348 ";; no-update-autoloads: t\n"
e542c600 349 ";; coding: utf-8\n"
a98f63d4
GM
350 ";; End:\n"
351 ";;; " basename
352 " ends here\n")))
353
a273d3e0
GM
354(defun autoload-ensure-default-file (file)
355 "Make sure that the autoload file FILE exists and if not create it."
356 (unless (file-exists-p file)
a98f63d4 357 (write-region (autoload-rubric file) nil file))
a273d3e0
GM
358 file)
359
360(defun autoload-insert-section-header (outbuf autoloads load-name file time)
361 "Insert the section-header line,
362which lists the file name and which functions are in it, etc."
363 (insert generate-autoload-section-header)
7abaf5cc 364 (prin1 `(autoloads ,autoloads ,load-name ,file ,time)
a273d3e0
GM
365 outbuf)
366 (terpri outbuf)
367 ;; Break that line at spaces, to avoid very long lines.
368 ;; Make each sub-line into a comment.
369 (with-current-buffer outbuf
370 (save-excursion
371 (forward-line -1)
372 (while (not (eolp))
373 (move-to-column 64)
374 (skip-chars-forward "^ \n")
375 (or (eolp)
376 (insert "\n" generate-autoload-section-continuation))))))
377
69135525
SM
378(defun autoload-find-file (file)
379 "Fetch file and put it in a temp buffer. Return the buffer."
380 ;; It is faster to avoid visiting the file.
3b979520 381 (setq file (expand-file-name file))
69135525
SM
382 (with-current-buffer (get-buffer-create " *autoload-file*")
383 (kill-all-local-variables)
384 (erase-buffer)
385 (setq buffer-undo-list t
386 buffer-read-only nil)
387 (emacs-lisp-mode)
3b979520 388 (setq default-directory (file-name-directory file))
69135525 389 (insert-file-contents file nil)
7aacaf15
GM
390 (let ((enable-local-variables :safe)
391 (enable-local-eval nil))
69135525
SM
392 (hack-local-variables))
393 (current-buffer)))
394
b17b8839
SM
395(defvar no-update-autoloads nil
396 "File local variable to prevent scanning this file for autoload cookies.")
397
3b979520 398(defun autoload-file-load-name (file)
f8ea0098
SM
399 "Compute the name that will be used to load FILE."
400 ;; OUTFILE should be the name of the global loaddefs.el file, which
401 ;; is expected to be at the root directory of the files we're
402 ;; scanning for autoloads and will be in the `load-path'.
403 (let* ((outfile (default-value 'generated-autoload-file))
404 (name (file-relative-name file (file-name-directory outfile)))
405 (names '())
406 (dir (file-name-directory outfile)))
407 ;; If `name' has directory components, only keep the
408 ;; last few that are really needed.
409 (while name
410 (setq name (directory-file-name name))
411 (push (file-name-nondirectory name) names)
412 (setq name (file-name-directory name)))
413 (while (not name)
414 (cond
415 ((null (cdr names)) (setq name (car names)))
416 ((file-exists-p (expand-file-name "subdirs.el" dir))
417 ;; FIXME: here we only check the existence of subdirs.el,
418 ;; without checking its content. This makes it generate wrong load
419 ;; names for cases like lisp/term which is not added to load-path.
420 (setq dir (expand-file-name (pop names) dir)))
421 (t (setq name (mapconcat 'identity names "/")))))
3b979520
SM
422 (if (string-match "\\.elc?\\(\\.\\|\\'\\)" name)
423 (substring name 0 (match-beginning 0))
424 name)))
425
0231f2dc
JB
426(defun generate-file-autoloads (file)
427 "Insert at point a loaddefs autoload section for FILE.
b17b8839 428Autoloads are generated for defuns and defmacros in FILE
da8826b4 429marked by `generate-autoload-cookie' (which see).
0231f2dc 430If FILE is being visited in a buffer, the contents of the buffer
b17b8839
SM
431are used.
432Return non-nil in the case where no autoloads were added at point."
0231f2dc 433 (interactive "fGenerate autoloads for file: ")
9ed7c8cb
CY
434 (let ((generated-autoload-file buffer-file-name))
435 (autoload-generate-file-autoloads file (current-buffer))))
ceea9b18 436
f8ea0098
SM
437(defvar print-readably)
438
66bd25ab 439
7d22ce18
SM
440(defun autoload--setup-output (otherbuf outbuf absfile load-name)
441 (let ((outbuf
442 (or (if otherbuf
443 ;; A file-local setting of
444 ;; autoload-generated-file says we
445 ;; should ignore OUTBUF.
446 nil
447 outbuf)
448 (autoload-find-destination absfile load-name)
449 ;; The file has autoload cookies, but they're
450 ;; already up-to-date. If OUTFILE is nil, the
451 ;; entries are in the expected OUTBUF,
452 ;; otherwise they're elsewhere.
453 (throw 'done otherbuf))))
454 (with-current-buffer outbuf
455 (point-marker))))
456
457(defun autoload--print-cookie-text (output-start load-name file)
458 (let ((standard-output (marker-buffer output-start)))
66bd25ab
SM
459 (search-forward generate-autoload-cookie)
460 (skip-chars-forward " \t")
461 (if (eolp)
462 (condition-case-unless-debug err
463 ;; Read the next form and make an autoload.
464 (let* ((form (prog1 (read (current-buffer))
465 (or (bolp) (forward-line 1))))
466 (autoload (make-autoload form load-name)))
467 (if autoload
468 nil
469 (setq autoload form))
470 (let ((autoload-print-form-outbuf
471 standard-output))
472 (autoload-print-form autoload)))
473 (error
474 (message "Autoload cookie error in %s:%s %S"
475 file (count-lines (point-min) (point)) err)))
476
477 ;; Copy the rest of the line to the output.
478 (princ (buffer-substring
479 (progn
480 ;; Back up over whitespace, to preserve it.
481 (skip-chars-backward " \f\t")
482 (if (= (char-after (1+ (point))) ? )
483 ;; Eat one space.
484 (forward-char 1))
485 (point))
7d22ce18 486 (progn (forward-line 1) (point)))))))
66bd25ab
SM
487
488(defvar autoload-builtin-package-versions nil)
489
438d6bb6
SM
490;; When called from `generate-file-autoloads' we should ignore
491;; `generated-autoload-file' altogether. When called from
492;; `update-file-autoloads' we don't know `outbuf'. And when called from
493;; `update-directory-autoloads' it's in between: we know the default
494;; `outbuf' but we should obey any file-local setting of
495;; `generated-autoload-file'.
496(defun autoload-generate-file-autoloads (file &optional outbuf outfile)
ceea9b18
SM
497 "Insert an autoload section for FILE in the appropriate buffer.
498Autoloads are generated for defuns and defmacros in FILE
499marked by `generate-autoload-cookie' (which see).
500If FILE is being visited in a buffer, the contents of the buffer are used.
438d6bb6 501OUTBUF is the buffer in which the autoload statements should be inserted.
986c5ad5 502If OUTBUF is nil, it will be determined by `autoload-generated-file'.
e66466a6 503
438d6bb6
SM
504If provided, OUTFILE is expected to be the file name of OUTBUF.
505If OUTFILE is non-nil and FILE specifies a `generated-autoload-file'
506different from OUTFILE, then OUTBUF is ignored.
507
1603d855 508Return non-nil if and only if FILE adds no autoloads to OUTFILE
438d6bb6 509\(or OUTBUF if OUTFILE is nil)."
1fad2b12 510 (catch 'done
66bd25ab 511 (let (load-name
1fad2b12 512 (print-length nil)
a113b3ca 513 (print-level nil)
1fad2b12
SM
514 (print-readably t) ; This does something in Lucid Emacs.
515 (float-output-format nil)
516 (visited (get-file-buffer file))
438d6bb6 517 (otherbuf nil)
1fad2b12 518 (absfile (expand-file-name file))
1fad2b12 519 ;; nil until we found a cookie.
66bd25ab 520 output-start)
1fad2b12
SM
521 (with-current-buffer (or visited
522 ;; It is faster to avoid visiting the file.
523 (autoload-find-file file))
524 ;; Obey the no-update-autoloads file local variable.
525 (unless no-update-autoloads
526 (message "Generating autoloads for %s..." file)
15120dec
CY
527 (setq load-name
528 (if (stringp generated-autoload-load-name)
529 generated-autoload-load-name
f8ea0098 530 (autoload-file-load-name absfile)))
ca7dd4cd
GM
531 ;; FIXME? Comparing file-names for equality with just equal
532 ;; is fragile, eg if one has an automounter prefix and one
533 ;; does not, but both refer to the same physical file.
f8ea0098 534 (when (and outfile
283430a1
EZ
535 (not
536 (if (memq system-type '(ms-dos windows-nt))
537 (equal (downcase outfile)
538 (downcase (autoload-generated-file)))
539 (equal outfile (autoload-generated-file)))))
f8ea0098 540 (setq otherbuf t))
1fad2b12
SM
541 (save-excursion
542 (save-restriction
543 (widen)
66bd25ab
SM
544 (when autoload-builtin-package-versions
545 (let ((version (lm-header "version"))
546 package)
547 (and version
548 (setq version (ignore-errors (version-to-list version)))
549 (setq package (or (lm-header "package")
550 (file-name-sans-extension
551 (file-name-nondirectory file))))
7d22ce18
SM
552 (setq output-start (autoload--setup-output
553 otherbuf outbuf absfile load-name))
554 (let ((standard-output (marker-buffer output-start))
555 (print-quoted t))
66bd25ab
SM
556 (princ `(push (purecopy
557 ',(cons (intern package) version))
558 package--builtin-versions))
4f85b479 559 (princ "\n")))))
66bd25ab 560
1fad2b12
SM
561 (goto-char (point-min))
562 (while (not (eobp))
563 (skip-chars-forward " \t\n\f")
564 (cond
565 ((looking-at (regexp-quote generate-autoload-cookie))
7d22ce18
SM
566 ;; If not done yet, figure out where to insert this text.
567 (unless output-start
568 (setq output-start (autoload--setup-output
569 otherbuf outbuf absfile load-name)))
570 (autoload--print-cookie-text output-start load-name file))
1fad2b12
SM
571 ((looking-at ";")
572 ;; Don't read the comment.
573 (forward-line 1))
574 (t
575 (forward-sexp 1)
576 (forward-line 1))))))
577
578 (when output-start
0b7750a9 579 (let ((secondary-autoloads-file-buf
f04a3be9 580 (if otherbuf (current-buffer))))
f8ea0098 581 (with-current-buffer (marker-buffer output-start)
0b7750a9
SM
582 (save-excursion
583 ;; Insert the section-header line which lists the file name
584 ;; and which functions are in it, etc.
585 (goto-char output-start)
f8ea0098
SM
586 (let ((relfile (file-relative-name absfile)))
587 (autoload-insert-section-header
588 (marker-buffer output-start)
66bd25ab 589 () load-name relfile
f8ea0098
SM
590 (if secondary-autoloads-file-buf
591 ;; MD5 checksums are much better because they do not
592 ;; change unless the file changes (so they'll be
593 ;; equal on two different systems and will change
594 ;; less often than time-stamps, thus leading to fewer
595 ;; unneeded changes causing spurious conflicts), but
596 ;; using time-stamps is a very useful optimization,
597 ;; so we use time-stamps for the main autoloads file
598 ;; (loaddefs.el) where we have special ways to
599 ;; circumvent the "random change problem", and MD5
600 ;; checksum in secondary autoload files where we do
601 ;; not need the time-stamp optimization because it is
602 ;; already provided by the primary autoloads file.
603 (md5 secondary-autoloads-file-buf
604 ;; We'd really want to just use
605 ;; `emacs-internal' instead.
606 nil nil 'emacs-mule-unix)
607 (nth 5 (file-attributes relfile))))
608 (insert ";;; Generated autoloads from " relfile "\n")))
0b7750a9 609 (insert generate-autoload-section-trailer))))
1fad2b12
SM
610 (message "Generating autoloads for %s...done" file))
611 (or visited
612 ;; We created this buffer, so we should kill it.
1c67aeaa 613 (kill-buffer (current-buffer))))
f8ea0098
SM
614 (or (not output-start)
615 ;; If the entries were added to some other buffer, then the file
616 ;; doesn't add entries to OUTFILE.
617 otherbuf))))
e2b6138f 618\f
e66466a6
SM
619(defun autoload-save-buffers ()
620 (while autoload-modified-buffers
621 (with-current-buffer (pop autoload-modified-buffers)
2d8a57ef
GM
622 (let ((version-control 'never))
623 (save-buffer)))))
e66466a6 624
0231f2dc 625;;;###autoload
9ed7c8cb
CY
626(defun update-file-autoloads (file &optional save-after outfile)
627 "Update the autoloads for FILE.
628If prefix arg SAVE-AFTER is non-nil, save the buffer too.
629
630If FILE binds `generated-autoload-file' as a file-local variable,
631autoloads are written into that file. Otherwise, the autoloads
632file is determined by OUTFILE. If called interactively, prompt
633for OUTFILE; if called from Lisp with OUTFILE nil, use the
634existing value of `generated-autoload-file'.
f7ed02ac
RS
635
636Return FILE if there was no autoload cookie in it, else nil."
9ed7c8cb
CY
637 (interactive (list (read-file-name "Update autoloads for file: ")
638 current-prefix-arg
639 (read-file-name "Write autoload definitions to file: ")))
640 (let* ((generated-autoload-file (or outfile generated-autoload-file))
641 (autoload-modified-buffers nil)
1fad2b12
SM
642 (no-autoloads (autoload-generate-file-autoloads file)))
643 (if autoload-modified-buffers
986c5ad5 644 (if save-after (autoload-save-buffers))
32226619 645 (if (called-interactively-p 'interactive)
986c5ad5 646 (message "Autoload section for %s is up to date." file)))
e66466a6 647 (if no-autoloads file)))
57536a83 648
f8ea0098 649(defun autoload-find-destination (file load-name)
57536a83
SM
650 "Find the destination point of the current buffer's autoloads.
651FILE is the file name of the current buffer.
652Returns a buffer whose point is placed at the requested location.
1fad2b12 653Returns nil if the file's autoloads are uptodate, otherwise
0b7750a9 654removes any prior now out-of-date autoload entries."
1fad2b12 655 (catch 'up-to-date
f8ea0098 656 (let* ((buf (current-buffer))
0b7750a9
SM
657 (existing-buffer (if buffer-file-name buf))
658 (found nil))
9ed7c8cb 659 (with-current-buffer (autoload-find-generated-file)
1fad2b12
SM
660 ;; This is to make generated-autoload-file have Unix EOLs, so
661 ;; that it is portable to all platforms.
4c0eb0d3
GM
662 (or (eq 0 (coding-system-eol-type buffer-file-coding-system))
663 (set-buffer-file-coding-system 'unix))
1fad2b12 664 (or (> (buffer-size) 0)
f8ea0098 665 (error "Autoloads file %s lacks boilerplate" buffer-file-name))
1fad2b12
SM
666 (or (file-writable-p buffer-file-name)
667 (error "Autoloads file %s is not writable" buffer-file-name))
668 (widen)
669 (goto-char (point-min))
670 ;; Look for the section for LOAD-NAME.
671 (while (and (not found)
672 (search-forward generate-autoload-section-header nil t))
673 (let ((form (autoload-read-section-header)))
674 (cond ((string= (nth 2 form) load-name)
675 ;; We found the section for this file.
676 ;; Check if it is up to date.
677 (let ((begin (match-beginning 0))
678 (last-time (nth 4 form))
679 (file-time (nth 5 (file-attributes file))))
680 (if (and (or (null existing-buffer)
681 (not (buffer-modified-p existing-buffer)))
0b7750a9
SM
682 (or
683 ;; last-time is the time-stamp (specifying
684 ;; the last time we looked at the file) and
685 ;; the file hasn't been changed since.
686 (and (listp last-time) (= (length last-time) 2)
687 (not (time-less-p last-time file-time)))
688 ;; last-time is an MD5 checksum instead.
689 (and (stringp last-time)
690 (equal last-time
691 (md5 buf nil nil 'emacs-mule)))))
1fad2b12
SM
692 (throw 'up-to-date nil)
693 (autoload-remove-section begin)
694 (setq found t))))
695 ((string< load-name (nth 2 form))
696 ;; We've come to a section alphabetically later than
697 ;; LOAD-NAME. We assume the file is in order and so
698 ;; there must be no section for LOAD-NAME. We will
699 ;; insert one before the section here.
700 (goto-char (match-beginning 0))
701 (setq found t)))))
702 (or found
703 (progn
704 ;; No later sections in the file. Put before the last page.
705 (goto-char (point-max))
706 (search-backward "\f" nil t)))
707 (unless (memq (current-buffer) autoload-modified-buffers)
708 (push (current-buffer) autoload-modified-buffers))
709 (current-buffer)))))
a273d3e0 710
a273d3e0
GM
711(defun autoload-remove-section (begin)
712 (goto-char begin)
713 (search-forward generate-autoload-section-trailer)
714 (delete-region begin (point)))
0231f2dc
JB
715
716;;;###autoload
56eebc29 717(defun update-directory-autoloads (&rest dirs)
9ed7c8cb
CY
718 "Update autoload definitions for Lisp files in the directories DIRS.
719In an interactive call, you must give one argument, the name of a
720single directory. In a call from Lisp, you can supply multiple
56eebc29
RS
721directories as separate arguments, but this usage is discouraged.
722
723The function does NOT recursively descend into subdirectories of the
9ed7c8cb
CY
724directory or directories specified.
725
726In an interactive call, prompt for a default output file for the
727autoload definitions, and temporarily bind the variable
728`generated-autoload-file' to this value. When called from Lisp,
729use the existing value of `generated-autoload-file'. If any Lisp
730file binds `generated-autoload-file' as a file-local variable,
731write its autoloads into the specified file instead."
b59c7256 732 (interactive "DUpdate autoloads from directory: ")
a85e4d58 733 (let* ((files-re (let ((tmp nil))
500fcedc
SM
734 (dolist (suf (get-load-suffixes))
735 (unless (string-match "\\.elc" suf) (push suf tmp)))
736 (concat "^[^=.].*" (regexp-opt tmp t) "\\'")))
a85e4d58 737 (files (apply 'nconc
a273d3e0
GM
738 (mapcar (lambda (dir)
739 (directory-files (expand-file-name dir)
a85e4d58 740 t files-re))
a273d3e0 741 dirs)))
48df920c 742 (done ())
a273d3e0 743 (this-time (current-time))
438d6bb6
SM
744 ;; Files with no autoload cookies or whose autoloads go to other
745 ;; files because of file-local autoload-generated-file settings.
746 (no-autoloads nil)
9ed7c8cb
CY
747 (autoload-modified-buffers nil)
748 (generated-autoload-file
749 (if (called-interactively-p 'interactive)
750 (read-file-name "Write autoload definitions to file: ")
751 generated-autoload-file)))
a273d3e0 752
9ed7c8cb 753 (with-current-buffer (autoload-find-generated-file)
e2b6138f 754 (save-excursion
a273d3e0 755 ;; Canonicalize file names and remove the autoload file itself.
1fad2b12
SM
756 (setq files (delete (file-relative-name buffer-file-name)
757 (mapcar 'file-relative-name files)))
a273d3e0 758
b59c7256
RM
759 (goto-char (point-min))
760 (while (search-forward generate-autoload-section-header nil t)
2336b6a9 761 (let* ((form (autoload-read-section-header))
b59c7256 762 (file (nth 3 form)))
a273d3e0
GM
763 (cond ((and (consp file) (stringp (car file)))
764 ;; This is a list of files that have no autoload cookies.
765 ;; There shouldn't be more than one such entry.
766 ;; Remove the obsolete section.
767 (autoload-remove-section (match-beginning 0))
768 (let ((last-time (nth 4 form)))
769 (dolist (file file)
770 (let ((file-time (nth 5 (file-attributes file))))
771 (when (and file-time
66dc9a0f 772 (not (time-less-p last-time file-time)))
a273d3e0
GM
773 ;; file unchanged
774 (push file no-autoloads)
775 (setq files (delete file files)))))))
776 ((not (stringp file)))
48df920c
SM
777 ((or (not (file-exists-p file))
778 ;; Remove duplicates as well, just in case.
1c67aeaa
SM
779 (member file done)
780 ;; If the file is actually excluded.
781 (member (expand-file-name file) autoload-excludes))
48df920c 782 ;; Remove the obsolete section.
a273d3e0 783 (autoload-remove-section (match-beginning 0)))
0b7750a9
SM
784 ((not (time-less-p (nth 4 form)
785 (nth 5 (file-attributes file))))
a273d3e0
GM
786 ;; File hasn't changed.
787 nil)
b59c7256 788 (t
438d6bb6
SM
789 (autoload-remove-section (match-beginning 0))
790 (if (autoload-generate-file-autoloads
f8ea0098 791 ;; Passing `current-buffer' makes it insert at point.
438d6bb6
SM
792 file (current-buffer) buffer-file-name)
793 (push file no-autoloads))))
48df920c 794 (push file done)
b59c7256 795 (setq files (delete file files)))))
a273d3e0 796 ;; Elements remaining in FILES have no existing autoload sections yet.
438d6bb6 797 (dolist (file files)
1c67aeaa
SM
798 (cond
799 ((member (expand-file-name file) autoload-excludes) nil)
f8ea0098
SM
800 ;; Passing nil as second argument forces
801 ;; autoload-generate-file-autoloads to look for the right
802 ;; spot where to insert each autoloads section.
1c67aeaa
SM
803 ((autoload-generate-file-autoloads file nil buffer-file-name)
804 (push file no-autoloads))))
438d6bb6 805
a273d3e0 806 (when no-autoloads
000d9923
MR
807 ;; Sort them for better readability.
808 (setq no-autoloads (sort no-autoloads 'string<))
a273d3e0
GM
809 ;; Add the `no-autoloads' section.
810 (goto-char (point-max))
811 (search-backward "\f" nil t)
812 (autoload-insert-section-header
813 (current-buffer) nil nil no-autoloads this-time)
814 (insert generate-autoload-section-trailer))
815
2d8a57ef
GM
816 (let ((version-control 'never))
817 (save-buffer))
438d6bb6
SM
818 ;; In case autoload entries were added to other files because of
819 ;; file-local autoload-generated-file settings.
820 (autoload-save-buffers))))
0231f2dc 821
1e0888f5
LH
822(define-obsolete-function-alias 'update-autoloads-from-directories
823 'update-directory-autoloads "22.1")
824
0231f2dc
JB
825;;;###autoload
826(defun batch-update-autoloads ()
b59c7256 827 "Update loaddefs.el autoloads in batch mode.
9ed7c8cb
CY
828Calls `update-directory-autoloads' on the command line arguments.
829Definitions are written to `generated-autoload-file' (which
830should be non-nil)."
5152da64 831 ;; For use during the Emacs build process only.
4a720484
GM
832 ;; Exclude those files that are preloaded on ALL platforms.
833 ;; These are the ones in loadup.el where "(load" is at the start
834 ;; of the line (crude, but it works).
5152da64 835 (unless autoload-excludes
4a720484
GM
836 (let ((default-directory (file-name-directory generated-autoload-file))
837 file)
838 (when (file-readable-p "loadup.el")
839 (with-temp-buffer
840 (insert-file-contents "loadup.el")
841 (while (re-search-forward "^(load \"\\([^\"]+\\)\"" nil t)
842 (setq file (match-string 1))
843 (or (string-match "\\.el\\'" file)
844 (setq file (format "%s.el" file)))
845 (or (string-match "\\`site-" file)
846 (push (expand-file-name file) autoload-excludes)))))))
3a4336e6
MB
847 (let ((args command-line-args-left))
848 (setq command-line-args-left nil)
849 (apply 'update-directory-autoloads args)))
0231f2dc
JB
850
851(provide 'autoload)
ffd56f97 852
c0274f38 853;;; autoload.el ends here