Mercurial > emacs
comparison lisp/emacs-lisp/autoload.el @ 39560:a05ad383618d
(autoload-ensure-default-file, autoload-insert-section-header)
(autoload-before-p, autoload-remove-section): New functions.
(generate-file-autoloads): Use them.
(update-file-autoloads): Use them. Return FILE if there's no cookie.
Make sure the autoload file is properly formatted when creating it.
(update-autoloads-from-directories): Use them as well.
Only update autoloads for files whose timestamp has changed.
Add a dummy entry to remember the files which had no autoload cookies.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Fri, 05 Oct 2001 09:29:11 +0000 |
parents | b174db545cfd |
children | c8f0d7b4bb40 |
comparison
equal
deleted
inserted
replaced
39559:5851ee3f83f5 | 39560:a05ad383618d |
---|---|
227 outbuf)) | 227 outbuf)) |
228 (terpri outbuf))) | 228 (terpri outbuf))) |
229 (let ((print-escape-newlines t) | 229 (let ((print-escape-newlines t) |
230 (print-escape-nonascii t)) | 230 (print-escape-nonascii t)) |
231 (print form outbuf))))))) | 231 (print form outbuf))))))) |
232 | |
233 (defun autoload-ensure-default-file (file) | |
234 "Make sure that the autoload file FILE exists and if not create it." | |
235 (unless (file-exists-p file) | |
236 (write-region | |
237 (concat ";;; " (file-name-nondirectory file) | |
238 " --- automatically extracted autoloads\n" | |
239 ";;\n" | |
240 ";;; Code:\n\n" | |
241 "\n;; Local Variables:\n" | |
242 ";; version-control: never\n" | |
243 ";; no-byte-compile: t\n" | |
244 ";; no-update-autoloads: t\n" | |
245 ";; End:\n" | |
246 ";;; " (file-name-nondirectory file) | |
247 "ends here\n") | |
248 nil file)) | |
249 file) | |
250 | |
251 (defun autoload-insert-section-header (outbuf autoloads load-name file time) | |
252 "Insert the section-header line, | |
253 which lists the file name and which functions are in it, etc." | |
254 (insert generate-autoload-section-header) | |
255 (prin1 (list 'autoloads autoloads load-name | |
256 (if (stringp file) (autoload-trim-file-name file) file) | |
257 time) | |
258 outbuf) | |
259 (terpri outbuf) | |
260 ;; Break that line at spaces, to avoid very long lines. | |
261 ;; Make each sub-line into a comment. | |
262 (with-current-buffer outbuf | |
263 (save-excursion | |
264 (forward-line -1) | |
265 (while (not (eolp)) | |
266 (move-to-column 64) | |
267 (skip-chars-forward "^ \n") | |
268 (or (eolp) | |
269 (insert "\n" generate-autoload-section-continuation)))))) | |
232 | 270 |
233 (defun generate-file-autoloads (file) | 271 (defun generate-file-autoloads (file) |
234 "Insert at point a loaddefs autoload section for FILE. | 272 "Insert at point a loaddefs autoload section for FILE. |
235 autoloads are generated for defuns and defmacros in FILE | 273 autoloads are generated for defuns and defmacros in FILE |
236 marked by `generate-autoload-cookie' (which see). | 274 marked by `generate-autoload-cookie' (which see). |
326 (setq output-end (point-marker)))) | 364 (setq output-end (point-marker)))) |
327 (if done-any | 365 (if done-any |
328 (progn | 366 (progn |
329 ;; Insert the section-header line | 367 ;; Insert the section-header line |
330 ;; which lists the file name and which functions are in it, etc. | 368 ;; which lists the file name and which functions are in it, etc. |
331 (insert generate-autoload-section-header) | 369 (autoload-insert-section-header outbuf autoloads-done load-name file |
332 (prin1 (list 'autoloads autoloads-done load-name | 370 (nth 5 (file-attributes file))) |
333 (autoload-trim-file-name file) | |
334 (nth 5 (file-attributes file))) | |
335 outbuf) | |
336 (terpri outbuf) | |
337 ;; Break that line at spaces, to avoid very long lines. | |
338 ;; Make each sub-line into a comment. | |
339 (with-current-buffer outbuf | |
340 (save-excursion | |
341 (forward-line -1) | |
342 (while (not (eolp)) | |
343 (move-to-column 64) | |
344 (skip-chars-forward "^ \n") | |
345 (or (eolp) | |
346 (insert "\n" generate-autoload-section-continuation))))) | |
347 (insert ";;; Generated autoloads from " | 371 (insert ";;; Generated autoloads from " |
348 (autoload-trim-file-name file) "\n") | 372 (autoload-trim-file-name file) "\n") |
349 (goto-char output-end) | 373 (goto-char output-end) |
350 (insert generate-autoload-section-trailer))) | 374 (insert generate-autoload-section-trailer))) |
351 (message "Generating autoloads for %s...done" file))) | 375 (message "Generating autoloads for %s...done" file))) |
352 | 376 |
353 ;;;###autoload | 377 ;;;###autoload |
354 (defun update-file-autoloads (file) | 378 (defun update-file-autoloads (file) |
355 "Update the autoloads for FILE in `generated-autoload-file' | 379 "Update the autoloads for FILE in `generated-autoload-file' |
356 \(which FILE might bind in its local variables)." | 380 \(which FILE might bind in its local variables). |
381 Return FILE if there was no autoload cookie in it." | |
357 (interactive "fUpdate autoloads for file: ") | 382 (interactive "fUpdate autoloads for file: ") |
358 (let ((load-name (let ((name (file-name-nondirectory file))) | 383 (let ((load-name (let ((name (file-name-nondirectory file))) |
359 (if (string-match "\\.elc?$" name) | 384 (if (string-match "\\.elc?$" name) |
360 (substring name 0 (match-beginning 0)) | 385 (substring name 0 (match-beginning 0)) |
361 name))) | 386 name))) |
362 (found nil) | 387 (found nil) |
363 (existing-buffer (get-file-buffer file))) | 388 (existing-buffer (get-file-buffer file)) |
389 (no-autoloads nil)) | |
364 (save-excursion | 390 (save-excursion |
365 ;; We want to get a value for generated-autoload-file from | 391 ;; We want to get a value for generated-autoload-file from |
366 ;; the local variables section if it's there. | 392 ;; the local variables section if it's there. |
367 (if existing-buffer | 393 (if existing-buffer |
368 (set-buffer existing-buffer)) | 394 (set-buffer existing-buffer)) |
369 ;; We must read/write the file without any code conversion, | 395 ;; We must read/write the file without any code conversion, |
370 ;; but still decode EOLs. | 396 ;; but still decode EOLs. |
371 (let ((coding-system-for-read 'raw-text)) | 397 (let ((coding-system-for-read 'raw-text)) |
372 (set-buffer (find-file-noselect | 398 (set-buffer (find-file-noselect |
373 (expand-file-name generated-autoload-file | 399 (autoload-ensure-default-file |
374 (expand-file-name "lisp" | 400 (expand-file-name generated-autoload-file |
375 source-directory)))) | 401 (expand-file-name "lisp" |
402 source-directory))))) | |
376 ;; This is to make generated-autoload-file have Unix EOLs, so | 403 ;; This is to make generated-autoload-file have Unix EOLs, so |
377 ;; that it is portable to all platforms. | 404 ;; that it is portable to all platforms. |
378 (setq buffer-file-coding-system 'raw-text-unix)) | 405 (setq buffer-file-coding-system 'raw-text-unix)) |
379 (or (> (buffer-size) 0) | 406 (or (> (buffer-size) 0) |
380 (error "Autoloads file %s does not exist" buffer-file-name)) | 407 (error "Autoloads file %s does not exist" buffer-file-name)) |
395 (last-time (nth 4 form)) | 422 (last-time (nth 4 form)) |
396 (file-time (nth 5 (file-attributes file)))) | 423 (file-time (nth 5 (file-attributes file)))) |
397 (if (and (or (null existing-buffer) | 424 (if (and (or (null existing-buffer) |
398 (not (buffer-modified-p existing-buffer))) | 425 (not (buffer-modified-p existing-buffer))) |
399 (listp last-time) (= (length last-time) 2) | 426 (listp last-time) (= (length last-time) 2) |
400 (or (> (car last-time) (car file-time)) | 427 (not (autoload-before-p last-time file-time))) |
401 (and (= (car last-time) (car file-time)) | |
402 (>= (nth 1 last-time) | |
403 (nth 1 file-time))))) | |
404 (progn | 428 (progn |
405 (if (interactive-p) | 429 (if (interactive-p) |
406 (message "\ | 430 (message "\ |
407 Autoload section for %s is up to date." | 431 Autoload section for %s is up to date." |
408 file)) | 432 file)) |
448 generate-autoload-cookie)) | 472 generate-autoload-cookie)) |
449 nil t) | 473 nil t) |
450 nil | 474 nil |
451 (if (interactive-p) | 475 (if (interactive-p) |
452 (message "%s has no autoloads" file)) | 476 (message "%s has no autoloads" file)) |
477 (setq no-autoloads t) | |
453 t) | 478 t) |
454 (or existing-buffer | 479 (or existing-buffer |
455 (kill-buffer (current-buffer)))))))) | 480 (kill-buffer (current-buffer)))))))) |
456 (generate-file-autoloads file)))) | 481 (generate-file-autoloads file)))) |
457 (and (interactive-p) | 482 (and (interactive-p) |
458 (buffer-modified-p) | 483 (buffer-modified-p) |
459 (save-buffer))))) | 484 (save-buffer)) |
485 | |
486 (if no-autoloads file)))) | |
487 | |
488 (defun autoload-before-p (time1 time2) | |
489 (or (< (car time1) (car time2)) | |
490 (and (= (car time1) (car time2)) | |
491 (< (nth 1 time1) (nth 1 time2))))) | |
492 | |
493 (defun autoload-remove-section (begin) | |
494 (goto-char begin) | |
495 (search-forward generate-autoload-section-trailer) | |
496 (delete-region begin (point))) | |
460 | 497 |
461 ;;;###autoload | 498 ;;;###autoload |
462 (defun update-autoloads-from-directories (&rest dirs) | 499 (defun update-autoloads-from-directories (&rest dirs) |
463 "\ | 500 "\ |
464 Update loaddefs.el with all the current autoloads from DIRS, and no old ones. | 501 Update loaddefs.el with all the current autoloads from DIRS, and no old ones. |
465 This uses `update-file-autoloads' (which see) do its work." | 502 This uses `update-file-autoloads' (which see) do its work." |
466 (interactive "DUpdate autoloads from directory: ") | 503 (interactive "DUpdate autoloads from directory: ") |
467 (let ((files (apply 'nconc | 504 (let* ((files (apply 'nconc |
468 (mapcar (function (lambda (dir) | 505 (mapcar (lambda (dir) |
469 (directory-files (expand-file-name dir) | 506 (directory-files (expand-file-name dir) |
470 t | 507 ;; FIXME: add .gz etc... |
471 "^[^=.].*\\.el$"))) | 508 t "^[^=.].*\\.el\\'")) |
472 dirs))) | 509 dirs))) |
473 autoloads-file | 510 (this-time (current-time)) |
474 top-dir) | 511 (no-autoloads nil) ;files with no autoload cookies. |
475 (setq autoloads-file | 512 (autoloads-file |
476 (expand-file-name generated-autoload-file | 513 (expand-file-name generated-autoload-file |
477 (expand-file-name "lisp" | 514 (expand-file-name "lisp" source-directory))) |
478 source-directory))) | 515 (top-dir (file-name-directory autoloads-file))) |
479 (setq top-dir (file-name-directory autoloads-file)) | 516 |
480 (save-excursion | 517 (with-current-buffer |
481 (set-buffer (find-file-noselect autoloads-file)) | 518 (find-file-noselect (autoload-ensure-default-file autoloads-file)) |
482 (save-excursion | 519 (save-excursion |
520 | |
521 ;; Canonicalize file names and remove the autoload file itself. | |
522 (setq files (delete (autoload-trim-file-name buffer-file-name) | |
523 (mapcar 'autoload-trim-file-name files))) | |
524 | |
483 (goto-char (point-min)) | 525 (goto-char (point-min)) |
484 (while (search-forward generate-autoload-section-header nil t) | 526 (while (search-forward generate-autoload-section-header nil t) |
485 (let* ((form (autoload-read-section-header)) | 527 (let* ((form (autoload-read-section-header)) |
486 (file (nth 3 form))) | 528 (file (nth 3 form))) |
487 (cond ((not (stringp file))) | 529 (cond ((and (consp file) (stringp (car file))) |
530 ;; This is a list of files that have no autoload cookies. | |
531 ;; There shouldn't be more than one such entry. | |
532 ;; Remove the obsolete section. | |
533 (autoload-remove-section (match-beginning 0)) | |
534 (let ((last-time (nth 4 form))) | |
535 (dolist (file file) | |
536 (let ((file-time (nth 5 (file-attributes file)))) | |
537 (when (and file-time | |
538 (not (autoload-before-p last-time | |
539 file-time))) | |
540 ;; file unchanged | |
541 (push file no-autoloads) | |
542 (setq files (delete file files))))))) | |
543 ((not (stringp file))) | |
488 ((not (file-exists-p (expand-file-name file top-dir))) | 544 ((not (file-exists-p (expand-file-name file top-dir))) |
489 ;; Remove the obsolete section. | 545 ;; Remove the obsolete section. |
490 (let ((begin (match-beginning 0))) | 546 (autoload-remove-section (match-beginning 0))) |
491 (search-forward generate-autoload-section-trailer) | 547 ((equal (nth 4 form) (nth 5 (file-attributes file))) |
492 (delete-region begin (point)))) | 548 ;; File hasn't changed. |
549 nil) | |
493 (t | 550 (t |
494 (update-file-autoloads file))) | 551 (update-file-autoloads file))) |
495 (setq files (delete file files))))) | 552 (setq files (delete file files))))) |
496 ;; Elements remaining in FILES have no existing autoload sections. | 553 ;; Elements remaining in FILES have no existing autoload sections yet. |
497 (mapcar 'update-file-autoloads files) | 554 (setq no-autoloads |
555 (append no-autoloads | |
556 (delq nil (mapcar 'update-file-autoloads files)))) | |
557 (when no-autoloads | |
558 ;; Add the `no-autoloads' section. | |
559 (goto-char (point-max)) | |
560 (search-backward "\f" nil t) | |
561 (autoload-insert-section-header | |
562 (current-buffer) nil nil no-autoloads this-time) | |
563 (insert generate-autoload-section-trailer)) | |
564 | |
498 (save-buffer)))) | 565 (save-buffer)))) |
499 | 566 |
500 ;;;###autoload | 567 ;;;###autoload |
501 (defun batch-update-autoloads () | 568 (defun batch-update-autoloads () |
502 "Update loaddefs.el autoloads in batch mode. | 569 "Update loaddefs.el autoloads in batch mode. |