Merge from trunk.
[bpt/emacs.git] / lisp / emacs-lisp / autoload.el
CommitLineData
500fcedc 1;; autoload.el --- maintain autoloads in loaddefs.el -*- lexical-binding: t -*-
c0274f38 2
ab422c4d 3;; Copyright (C) 1991-1997, 2001-2013 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
SM
439(defun autoload--insert-text (output-start otherbuf outbuf absfile
440 load-name printfun)
441 ;; If not done yet, figure out where to insert this text.
442 (unless (marker-buffer output-start)
443 (let ((outbuf
444 (or (if otherbuf
445 ;; A file-local setting of
446 ;; autoload-generated-file says we
447 ;; should ignore OUTBUF.
448 nil
449 outbuf)
450 (autoload-find-destination absfile load-name)
451 ;; The file has autoload cookies, but they're
452 ;; already up-to-date. If OUTFILE is nil, the
453 ;; entries are in the expected OUTBUF,
454 ;; otherwise they're elsewhere.
455 (throw 'done otherbuf))))
456 (with-current-buffer outbuf
457 (move-marker output-start (point) outbuf))))
458 (let ((standard-output (marker-buffer output-start)))
459 (funcall printfun)))
460
461(defun autoload--insert-cookie-text (output-start otherbuf outbuf absfile
462 load-name file)
463 (autoload--insert-text
464 output-start otherbuf outbuf absfile load-name
465 (lambda ()
466 (search-forward generate-autoload-cookie)
467 (skip-chars-forward " \t")
468 (if (eolp)
469 (condition-case-unless-debug err
470 ;; Read the next form and make an autoload.
471 (let* ((form (prog1 (read (current-buffer))
472 (or (bolp) (forward-line 1))))
473 (autoload (make-autoload form load-name)))
474 (if autoload
475 nil
476 (setq autoload form))
477 (let ((autoload-print-form-outbuf
478 standard-output))
479 (autoload-print-form autoload)))
480 (error
481 (message "Autoload cookie error in %s:%s %S"
482 file (count-lines (point-min) (point)) err)))
483
484 ;; Copy the rest of the line to the output.
485 (princ (buffer-substring
486 (progn
487 ;; Back up over whitespace, to preserve it.
488 (skip-chars-backward " \f\t")
489 (if (= (char-after (1+ (point))) ? )
490 ;; Eat one space.
491 (forward-char 1))
492 (point))
493 (progn (forward-line 1) (point))))))))
494
495(defvar autoload-builtin-package-versions nil)
496
438d6bb6
SM
497;; When called from `generate-file-autoloads' we should ignore
498;; `generated-autoload-file' altogether. When called from
499;; `update-file-autoloads' we don't know `outbuf'. And when called from
500;; `update-directory-autoloads' it's in between: we know the default
501;; `outbuf' but we should obey any file-local setting of
502;; `generated-autoload-file'.
503(defun autoload-generate-file-autoloads (file &optional outbuf outfile)
ceea9b18
SM
504 "Insert an autoload section for FILE in the appropriate buffer.
505Autoloads are generated for defuns and defmacros in FILE
506marked by `generate-autoload-cookie' (which see).
507If FILE is being visited in a buffer, the contents of the buffer are used.
438d6bb6 508OUTBUF is the buffer in which the autoload statements should be inserted.
986c5ad5 509If OUTBUF is nil, it will be determined by `autoload-generated-file'.
e66466a6 510
438d6bb6
SM
511If provided, OUTFILE is expected to be the file name of OUTBUF.
512If OUTFILE is non-nil and FILE specifies a `generated-autoload-file'
513different from OUTFILE, then OUTBUF is ignored.
514
1603d855 515Return non-nil if and only if FILE adds no autoloads to OUTFILE
438d6bb6 516\(or OUTBUF if OUTFILE is nil)."
1fad2b12 517 (catch 'done
66bd25ab 518 (let (load-name
1fad2b12 519 (print-length nil)
a113b3ca 520 (print-level nil)
1fad2b12
SM
521 (print-readably t) ; This does something in Lucid Emacs.
522 (float-output-format nil)
523 (visited (get-file-buffer file))
438d6bb6 524 (otherbuf nil)
1fad2b12 525 (absfile (expand-file-name file))
1fad2b12 526 ;; nil until we found a cookie.
66bd25ab 527 output-start)
1fad2b12
SM
528 (with-current-buffer (or visited
529 ;; It is faster to avoid visiting the file.
530 (autoload-find-file file))
531 ;; Obey the no-update-autoloads file local variable.
532 (unless no-update-autoloads
533 (message "Generating autoloads for %s..." file)
15120dec
CY
534 (setq load-name
535 (if (stringp generated-autoload-load-name)
536 generated-autoload-load-name
f8ea0098
SM
537 (autoload-file-load-name absfile)))
538 (when (and outfile
283430a1
EZ
539 (not
540 (if (memq system-type '(ms-dos windows-nt))
541 (equal (downcase outfile)
542 (downcase (autoload-generated-file)))
543 (equal outfile (autoload-generated-file)))))
f8ea0098 544 (setq otherbuf t))
1fad2b12
SM
545 (save-excursion
546 (save-restriction
547 (widen)
66bd25ab
SM
548 (when autoload-builtin-package-versions
549 (let ((version (lm-header "version"))
550 package)
551 (and version
552 (setq version (ignore-errors (version-to-list version)))
553 (setq package (or (lm-header "package")
554 (file-name-sans-extension
555 (file-name-nondirectory file))))
556 (setq output-start (make-marker))
557 (autoload--insert-text
558 output-start otherbuf outbuf absfile load-name
559 (lambda ()
560 (princ `(push (purecopy
561 ',(cons (intern package) version))
562 package--builtin-versions))
563 (newline))))))
564
1fad2b12
SM
565 (goto-char (point-min))
566 (while (not (eobp))
567 (skip-chars-forward " \t\n\f")
568 (cond
569 ((looking-at (regexp-quote generate-autoload-cookie))
66bd25ab
SM
570 (unless output-start (setq output-start (make-marker)))
571 (autoload--insert-cookie-text
572 output-start otherbuf outbuf absfile load-name file))
1fad2b12
SM
573 ((looking-at ";")
574 ;; Don't read the comment.
575 (forward-line 1))
576 (t
577 (forward-sexp 1)
578 (forward-line 1))))))
579
580 (when output-start
0b7750a9 581 (let ((secondary-autoloads-file-buf
f04a3be9 582 (if otherbuf (current-buffer))))
f8ea0098 583 (with-current-buffer (marker-buffer output-start)
0b7750a9
SM
584 (save-excursion
585 ;; Insert the section-header line which lists the file name
586 ;; and which functions are in it, etc.
587 (goto-char output-start)
f8ea0098
SM
588 (let ((relfile (file-relative-name absfile)))
589 (autoload-insert-section-header
590 (marker-buffer output-start)
66bd25ab 591 () load-name relfile
f8ea0098
SM
592 (if secondary-autoloads-file-buf
593 ;; MD5 checksums are much better because they do not
594 ;; change unless the file changes (so they'll be
595 ;; equal on two different systems and will change
596 ;; less often than time-stamps, thus leading to fewer
597 ;; unneeded changes causing spurious conflicts), but
598 ;; using time-stamps is a very useful optimization,
599 ;; so we use time-stamps for the main autoloads file
600 ;; (loaddefs.el) where we have special ways to
601 ;; circumvent the "random change problem", and MD5
602 ;; checksum in secondary autoload files where we do
603 ;; not need the time-stamp optimization because it is
604 ;; already provided by the primary autoloads file.
605 (md5 secondary-autoloads-file-buf
606 ;; We'd really want to just use
607 ;; `emacs-internal' instead.
608 nil nil 'emacs-mule-unix)
609 (nth 5 (file-attributes relfile))))
610 (insert ";;; Generated autoloads from " relfile "\n")))
0b7750a9 611 (insert generate-autoload-section-trailer))))
1fad2b12
SM
612 (message "Generating autoloads for %s...done" file))
613 (or visited
614 ;; We created this buffer, so we should kill it.
1c67aeaa 615 (kill-buffer (current-buffer))))
f8ea0098
SM
616 (or (not output-start)
617 ;; If the entries were added to some other buffer, then the file
618 ;; doesn't add entries to OUTFILE.
619 otherbuf))))
e2b6138f 620\f
e66466a6
SM
621(defun autoload-save-buffers ()
622 (while autoload-modified-buffers
623 (with-current-buffer (pop autoload-modified-buffers)
2d8a57ef
GM
624 (let ((version-control 'never))
625 (save-buffer)))))
e66466a6 626
0231f2dc 627;;;###autoload
9ed7c8cb
CY
628(defun update-file-autoloads (file &optional save-after outfile)
629 "Update the autoloads for FILE.
630If prefix arg SAVE-AFTER is non-nil, save the buffer too.
631
632If FILE binds `generated-autoload-file' as a file-local variable,
633autoloads are written into that file. Otherwise, the autoloads
634file is determined by OUTFILE. If called interactively, prompt
635for OUTFILE; if called from Lisp with OUTFILE nil, use the
636existing value of `generated-autoload-file'.
f7ed02ac
RS
637
638Return FILE if there was no autoload cookie in it, else nil."
9ed7c8cb
CY
639 (interactive (list (read-file-name "Update autoloads for file: ")
640 current-prefix-arg
641 (read-file-name "Write autoload definitions to file: ")))
642 (let* ((generated-autoload-file (or outfile generated-autoload-file))
643 (autoload-modified-buffers nil)
1fad2b12
SM
644 (no-autoloads (autoload-generate-file-autoloads file)))
645 (if autoload-modified-buffers
986c5ad5 646 (if save-after (autoload-save-buffers))
32226619 647 (if (called-interactively-p 'interactive)
986c5ad5 648 (message "Autoload section for %s is up to date." file)))
e66466a6 649 (if no-autoloads file)))
57536a83 650
f8ea0098 651(defun autoload-find-destination (file load-name)
57536a83
SM
652 "Find the destination point of the current buffer's autoloads.
653FILE is the file name of the current buffer.
654Returns a buffer whose point is placed at the requested location.
1fad2b12 655Returns nil if the file's autoloads are uptodate, otherwise
0b7750a9 656removes any prior now out-of-date autoload entries."
1fad2b12 657 (catch 'up-to-date
f8ea0098 658 (let* ((buf (current-buffer))
0b7750a9
SM
659 (existing-buffer (if buffer-file-name buf))
660 (found nil))
9ed7c8cb 661 (with-current-buffer (autoload-find-generated-file)
1fad2b12
SM
662 ;; This is to make generated-autoload-file have Unix EOLs, so
663 ;; that it is portable to all platforms.
4c0eb0d3
GM
664 (or (eq 0 (coding-system-eol-type buffer-file-coding-system))
665 (set-buffer-file-coding-system 'unix))
1fad2b12 666 (or (> (buffer-size) 0)
f8ea0098 667 (error "Autoloads file %s lacks boilerplate" buffer-file-name))
1fad2b12
SM
668 (or (file-writable-p buffer-file-name)
669 (error "Autoloads file %s is not writable" buffer-file-name))
670 (widen)
671 (goto-char (point-min))
672 ;; Look for the section for LOAD-NAME.
673 (while (and (not found)
674 (search-forward generate-autoload-section-header nil t))
675 (let ((form (autoload-read-section-header)))
676 (cond ((string= (nth 2 form) load-name)
677 ;; We found the section for this file.
678 ;; Check if it is up to date.
679 (let ((begin (match-beginning 0))
680 (last-time (nth 4 form))
681 (file-time (nth 5 (file-attributes file))))
682 (if (and (or (null existing-buffer)
683 (not (buffer-modified-p existing-buffer)))
0b7750a9
SM
684 (or
685 ;; last-time is the time-stamp (specifying
686 ;; the last time we looked at the file) and
687 ;; the file hasn't been changed since.
688 (and (listp last-time) (= (length last-time) 2)
689 (not (time-less-p last-time file-time)))
690 ;; last-time is an MD5 checksum instead.
691 (and (stringp last-time)
692 (equal last-time
693 (md5 buf nil nil 'emacs-mule)))))
1fad2b12
SM
694 (throw 'up-to-date nil)
695 (autoload-remove-section begin)
696 (setq found t))))
697 ((string< load-name (nth 2 form))
698 ;; We've come to a section alphabetically later than
699 ;; LOAD-NAME. We assume the file is in order and so
700 ;; there must be no section for LOAD-NAME. We will
701 ;; insert one before the section here.
702 (goto-char (match-beginning 0))
703 (setq found t)))))
704 (or found
705 (progn
706 ;; No later sections in the file. Put before the last page.
707 (goto-char (point-max))
708 (search-backward "\f" nil t)))
709 (unless (memq (current-buffer) autoload-modified-buffers)
710 (push (current-buffer) autoload-modified-buffers))
711 (current-buffer)))))
a273d3e0 712
a273d3e0
GM
713(defun autoload-remove-section (begin)
714 (goto-char begin)
715 (search-forward generate-autoload-section-trailer)
716 (delete-region begin (point)))
0231f2dc
JB
717
718;;;###autoload
56eebc29 719(defun update-directory-autoloads (&rest dirs)
9ed7c8cb
CY
720 "Update autoload definitions for Lisp files in the directories DIRS.
721In an interactive call, you must give one argument, the name of a
722single directory. In a call from Lisp, you can supply multiple
56eebc29
RS
723directories as separate arguments, but this usage is discouraged.
724
725The function does NOT recursively descend into subdirectories of the
9ed7c8cb
CY
726directory or directories specified.
727
728In an interactive call, prompt for a default output file for the
729autoload definitions, and temporarily bind the variable
730`generated-autoload-file' to this value. When called from Lisp,
731use the existing value of `generated-autoload-file'. If any Lisp
732file binds `generated-autoload-file' as a file-local variable,
733write its autoloads into the specified file instead."
b59c7256 734 (interactive "DUpdate autoloads from directory: ")
a85e4d58 735 (let* ((files-re (let ((tmp nil))
500fcedc
SM
736 (dolist (suf (get-load-suffixes))
737 (unless (string-match "\\.elc" suf) (push suf tmp)))
738 (concat "^[^=.].*" (regexp-opt tmp t) "\\'")))
a85e4d58 739 (files (apply 'nconc
a273d3e0
GM
740 (mapcar (lambda (dir)
741 (directory-files (expand-file-name dir)
a85e4d58 742 t files-re))
a273d3e0 743 dirs)))
48df920c 744 (done ())
a273d3e0 745 (this-time (current-time))
438d6bb6
SM
746 ;; Files with no autoload cookies or whose autoloads go to other
747 ;; files because of file-local autoload-generated-file settings.
748 (no-autoloads nil)
9ed7c8cb
CY
749 (autoload-modified-buffers nil)
750 (generated-autoload-file
751 (if (called-interactively-p 'interactive)
752 (read-file-name "Write autoload definitions to file: ")
753 generated-autoload-file)))
a273d3e0 754
9ed7c8cb 755 (with-current-buffer (autoload-find-generated-file)
e2b6138f 756 (save-excursion
a273d3e0 757 ;; Canonicalize file names and remove the autoload file itself.
1fad2b12
SM
758 (setq files (delete (file-relative-name buffer-file-name)
759 (mapcar 'file-relative-name files)))
a273d3e0 760
b59c7256
RM
761 (goto-char (point-min))
762 (while (search-forward generate-autoload-section-header nil t)
2336b6a9 763 (let* ((form (autoload-read-section-header))
b59c7256 764 (file (nth 3 form)))
a273d3e0
GM
765 (cond ((and (consp file) (stringp (car file)))
766 ;; This is a list of files that have no autoload cookies.
767 ;; There shouldn't be more than one such entry.
768 ;; Remove the obsolete section.
769 (autoload-remove-section (match-beginning 0))
770 (let ((last-time (nth 4 form)))
771 (dolist (file file)
772 (let ((file-time (nth 5 (file-attributes file))))
773 (when (and file-time
66dc9a0f 774 (not (time-less-p last-time file-time)))
a273d3e0
GM
775 ;; file unchanged
776 (push file no-autoloads)
777 (setq files (delete file files)))))))
778 ((not (stringp file)))
48df920c
SM
779 ((or (not (file-exists-p file))
780 ;; Remove duplicates as well, just in case.
1c67aeaa
SM
781 (member file done)
782 ;; If the file is actually excluded.
783 (member (expand-file-name file) autoload-excludes))
48df920c 784 ;; Remove the obsolete section.
a273d3e0 785 (autoload-remove-section (match-beginning 0)))
0b7750a9
SM
786 ((not (time-less-p (nth 4 form)
787 (nth 5 (file-attributes file))))
a273d3e0
GM
788 ;; File hasn't changed.
789 nil)
b59c7256 790 (t
438d6bb6
SM
791 (autoload-remove-section (match-beginning 0))
792 (if (autoload-generate-file-autoloads
f8ea0098 793 ;; Passing `current-buffer' makes it insert at point.
438d6bb6
SM
794 file (current-buffer) buffer-file-name)
795 (push file no-autoloads))))
48df920c 796 (push file done)
b59c7256 797 (setq files (delete file files)))))
a273d3e0 798 ;; Elements remaining in FILES have no existing autoload sections yet.
438d6bb6 799 (dolist (file files)
1c67aeaa
SM
800 (cond
801 ((member (expand-file-name file) autoload-excludes) nil)
f8ea0098
SM
802 ;; Passing nil as second argument forces
803 ;; autoload-generate-file-autoloads to look for the right
804 ;; spot where to insert each autoloads section.
1c67aeaa
SM
805 ((autoload-generate-file-autoloads file nil buffer-file-name)
806 (push file no-autoloads))))
438d6bb6 807
a273d3e0 808 (when no-autoloads
000d9923
MR
809 ;; Sort them for better readability.
810 (setq no-autoloads (sort no-autoloads 'string<))
a273d3e0
GM
811 ;; Add the `no-autoloads' section.
812 (goto-char (point-max))
813 (search-backward "\f" nil t)
814 (autoload-insert-section-header
815 (current-buffer) nil nil no-autoloads this-time)
816 (insert generate-autoload-section-trailer))
817
2d8a57ef
GM
818 (let ((version-control 'never))
819 (save-buffer))
438d6bb6
SM
820 ;; In case autoload entries were added to other files because of
821 ;; file-local autoload-generated-file settings.
822 (autoload-save-buffers))))
0231f2dc 823
1e0888f5
LH
824(define-obsolete-function-alias 'update-autoloads-from-directories
825 'update-directory-autoloads "22.1")
826
0231f2dc
JB
827;;;###autoload
828(defun batch-update-autoloads ()
b59c7256 829 "Update loaddefs.el autoloads in batch mode.
9ed7c8cb
CY
830Calls `update-directory-autoloads' on the command line arguments.
831Definitions are written to `generated-autoload-file' (which
832should be non-nil)."
5152da64 833 ;; For use during the Emacs build process only.
4a720484
GM
834 ;; Exclude those files that are preloaded on ALL platforms.
835 ;; These are the ones in loadup.el where "(load" is at the start
836 ;; of the line (crude, but it works).
5152da64 837 (unless autoload-excludes
4a720484
GM
838 (let ((default-directory (file-name-directory generated-autoload-file))
839 file)
840 (when (file-readable-p "loadup.el")
841 (with-temp-buffer
842 (insert-file-contents "loadup.el")
843 (while (re-search-forward "^(load \"\\([^\"]+\\)\"" nil t)
844 (setq file (match-string 1))
845 (or (string-match "\\.el\\'" file)
846 (setq file (format "%s.el" file)))
847 (or (string-match "\\`site-" file)
848 (push (expand-file-name file) autoload-excludes)))))))
3a4336e6
MB
849 (let ((args command-line-args-left))
850 (setq command-line-args-left nil)
851 (apply 'update-directory-autoloads args)))
0231f2dc
JB
852
853(provide 'autoload)
ffd56f97 854
c0274f38 855;;; autoload.el ends here