Mercurial > emacs
comparison lisp/emacs-lisp/autoload.el @ 88155:d7ddb3e565de
sync with trunk
author | Henrik Enberg <henrik.enberg@telia.com> |
---|---|
date | Mon, 16 Jan 2006 00:03:54 +0000 |
parents | 0d8b17d428b5 |
children |
comparison
equal
deleted
inserted
replaced
88154:8ce476d3ba36 | 88155:d7ddb3e565de |
---|---|
1 ;;; autoload.el --- maintain autoloads in loaddefs.el | 1 ;; autoload.el --- maintain autoloads in loaddefs.el |
2 | 2 |
3 ;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2001 | 3 ;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2001, 2002, 2003, |
4 ;; Free Software Foundation, Inc. | 4 ;; 2004, 2005 Free Software Foundation, Inc. |
5 | 5 |
6 ;; Author: Roland McGrath <roland@gnu.org> | 6 ;; Author: Roland McGrath <roland@gnu.org> |
7 ;; Keywords: maint | 7 ;; Keywords: maint |
8 | 8 |
9 ;; This file is part of GNU Emacs. | 9 ;; This file is part of GNU Emacs. |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 ;; GNU General Public License for more details. | 19 ;; GNU General Public License for more details. |
20 | 20 |
21 ;; You should have received a copy of the GNU General Public License | 21 ;; You should have received a copy of the GNU General Public License |
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the | 22 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
24 ;; Boston, MA 02111-1307, USA. | 24 ;; Boston, MA 02110-1301, USA. |
25 | 25 |
26 ;;; Commentary: | 26 ;;; Commentary: |
27 | 27 |
28 ;; This code helps GNU Emacs maintainers keep the loaddefs.el file up to | 28 ;; This code helps GNU Emacs maintainers keep the loaddefs.el file up to |
29 ;; date. It interprets magic cookies of the form ";;;###autoload" in | 29 ;; date. It interprets magic cookies of the form ";;;###autoload" in |
32 | 32 |
33 ;;; Code: | 33 ;;; Code: |
34 | 34 |
35 (require 'lisp-mode) ;for `doc-string-elt' properties. | 35 (require 'lisp-mode) ;for `doc-string-elt' properties. |
36 (require 'help-fns) ;for help-add-fundoc-usage. | 36 (require 'help-fns) ;for help-add-fundoc-usage. |
37 (eval-when-compile (require 'cl)) | |
37 | 38 |
38 (defvar generated-autoload-file "loaddefs.el" | 39 (defvar generated-autoload-file "loaddefs.el" |
39 "*File \\[update-file-autoloads] puts autoloads into. | 40 "*File \\[update-file-autoloads] puts autoloads into. |
40 A `.el' file can set this in its local variables section to make its | 41 A `.el' file can set this in its local variables section to make its |
41 autoloads go somewhere else. The autoload file is assumed to contain a | 42 autoloads go somewhere else. The autoload file is assumed to contain a |
69 Returns nil if FORM is not a special autoload form (i.e. a function definition | 70 Returns nil if FORM is not a special autoload form (i.e. a function definition |
70 or macro definition or a defcustom)." | 71 or macro definition or a defcustom)." |
71 (let ((car (car-safe form)) expand) | 72 (let ((car (car-safe form)) expand) |
72 (cond | 73 (cond |
73 ;; For complex cases, try again on the macro-expansion. | 74 ;; For complex cases, try again on the macro-expansion. |
74 ((and (memq car '(easy-mmode-define-global-mode | 75 ((and (memq car '(easy-mmode-define-global-mode define-global-minor-mode |
75 easy-mmode-define-minor-mode define-minor-mode)) | 76 easy-mmode-define-minor-mode define-minor-mode)) |
76 (setq expand (let ((load-file-name file)) (macroexpand form))) | 77 (setq expand (let ((load-file-name file)) (macroexpand form))) |
77 (eq (car expand) 'progn) | 78 (eq (car expand) 'progn) |
78 (memq :autoload-end expand)) | 79 (memq :autoload-end expand)) |
79 (let ((end (memq :autoload-end expand))) | 80 (let ((end (memq :autoload-end expand))) |
83 (mapcar (lambda (form) (make-autoload form file)) | 84 (mapcar (lambda (form) (make-autoload form file)) |
84 (cdr expand))))) | 85 (cdr expand))))) |
85 | 86 |
86 ;; For special function-like operators, use the `autoload' function. | 87 ;; For special function-like operators, use the `autoload' function. |
87 ((memq car '(defun define-skeleton defmacro define-derived-mode | 88 ((memq car '(defun define-skeleton defmacro define-derived-mode |
88 define-generic-mode easy-mmode-define-minor-mode | 89 define-compilation-mode define-generic-mode |
89 easy-mmode-define-global-mode | 90 easy-mmode-define-global-mode define-global-minor-mode |
90 define-minor-mode defun* defmacro*)) | 91 easy-mmode-define-minor-mode define-minor-mode |
92 defun* defmacro*)) | |
91 (let* ((macrop (memq car '(defmacro defmacro*))) | 93 (let* ((macrop (memq car '(defmacro defmacro*))) |
92 (name (nth 1 form)) | 94 (name (nth 1 form)) |
93 (args (if (memq car '(defun defmacro defun* defmacro*)) | 95 (args (case car |
94 (nth 2 form) t)) | 96 ((defun defmacro defun* defmacro*) (nth 2 form)) |
97 ((define-skeleton) '(&optional str arg)) | |
98 ((define-generic-mode define-derived-mode | |
99 define-compilation-mode) nil) | |
100 (t))) | |
95 (body (nthcdr (get car 'doc-string-elt) form)) | 101 (body (nthcdr (get car 'doc-string-elt) form)) |
96 (doc (if (stringp (car body)) (pop body)))) | 102 (doc (if (stringp (car body)) (pop body)))) |
97 (when (listp args) | 103 (when (listp args) |
98 ;; Add the usage form at the end where describe-function-1 | 104 ;; Add the usage form at the end where describe-function-1 |
99 ;; can recover it. | 105 ;; can recover it. |
101 ;; `define-generic-mode' quotes the name, so take care of that | 107 ;; `define-generic-mode' quotes the name, so take care of that |
102 (list 'autoload (if (listp name) name (list 'quote name)) file doc | 108 (list 'autoload (if (listp name) name (list 'quote name)) file doc |
103 (or (and (memq car '(define-skeleton define-derived-mode | 109 (or (and (memq car '(define-skeleton define-derived-mode |
104 define-generic-mode | 110 define-generic-mode |
105 easy-mmode-define-global-mode | 111 easy-mmode-define-global-mode |
112 define-global-minor-mode | |
106 easy-mmode-define-minor-mode | 113 easy-mmode-define-minor-mode |
107 define-minor-mode)) t) | 114 define-minor-mode)) t) |
108 (eq (car-safe (car body)) 'interactive)) | 115 (eq (car-safe (car body)) 'interactive)) |
109 (if macrop (list 'quote 'macro) nil)))) | 116 (if macrop (list 'quote 'macro) nil)))) |
110 | 117 |
115 (doc (car-safe (cdr-safe (cdr-safe (cdr-safe form))))) | 122 (doc (car-safe (cdr-safe (cdr-safe (cdr-safe form))))) |
116 ;; (rest (cdr-safe (cdr-safe (cdr-safe (cdr-safe form))))) | 123 ;; (rest (cdr-safe (cdr-safe (cdr-safe (cdr-safe form))))) |
117 ) | 124 ) |
118 `(progn | 125 `(progn |
119 (defvar ,varname ,init ,doc) | 126 (defvar ,varname ,init ,doc) |
120 (custom-autoload ',varname ,file)))) | 127 (custom-autoload ',varname ,file) |
128 ;; The use of :require in a defcustom can be annoying, especially | |
129 ;; when defcustoms are moved from one file to another between | |
130 ;; releases because the :require arg gets placed in the user's | |
131 ;; .emacs. In order for autoloaded minor modes not to need the | |
132 ;; use of :require, we arrange to store their :setter. | |
133 ,(let ((setter (condition-case nil | |
134 (cadr (memq :set form)) | |
135 (error nil)))) | |
136 (if (equal setter ''custom-set-minor-mode) | |
137 `(put ',varname 'custom-set 'custom-set-minor-mode)))))) | |
138 | |
139 ((eq car 'defgroup) | |
140 ;; In Emacs this is normally handled separately by cus-dep.el, but for | |
141 ;; third party packages, it can be convenient to explicitly autoload | |
142 ;; a group. | |
143 (let ((groupname (nth 1 form))) | |
144 `(let ((loads (get ',groupname 'custom-loads))) | |
145 (if (member ',file loads) nil | |
146 (put ',groupname 'custom-loads (cons ',file loads)))))) | |
121 | 147 |
122 ;; nil here indicates that this is not a special autoload form. | 148 ;; nil here indicates that this is not a special autoload form. |
123 (t nil)))) | 149 (t nil)))) |
124 | 150 |
125 ;; Forms which have doc-strings which should be printed specially. | 151 ;; Forms which have doc-strings which should be printed specially. |
127 ;; the doc-string in FORM. | 153 ;; the doc-string in FORM. |
128 ;; Those properties are now set in lisp-mode.el. | 154 ;; Those properties are now set in lisp-mode.el. |
129 | 155 |
130 | 156 |
131 (defun autoload-trim-file-name (file) | 157 (defun autoload-trim-file-name (file) |
132 ;; Returns a relative pathname of FILE | 158 ;; Returns a relative file path for FILE |
133 ;; starting from the directory that loaddefs.el is in. | 159 ;; starting from the directory that loaddefs.el is in. |
134 ;; That is normally a directory in load-path, | 160 ;; That is normally a directory in load-path, |
135 ;; which means Emacs will be able to find FILE when it looks. | 161 ;; which means Emacs will be able to find FILE when it looks. |
136 ;; Any extra directory names here would prevent finding the file. | 162 ;; Any extra directory names here would prevent finding the file. |
137 (setq file (expand-file-name file)) | 163 (setq file (expand-file-name file)) |
157 (while (search-forward generate-autoload-section-continuation nil t) | 183 (while (search-forward generate-autoload-section-continuation nil t) |
158 (replace-match " ")) | 184 (replace-match " ")) |
159 (goto-char (point-min)) | 185 (goto-char (point-min)) |
160 (read (current-buffer)))))) | 186 (read (current-buffer)))))) |
161 | 187 |
162 (defvar autoload-print-form-outbuf) | 188 (defvar autoload-print-form-outbuf nil |
189 "Buffer which gets the output of `autoload-print-form'.") | |
163 | 190 |
164 (defun autoload-print-form (form) | 191 (defun autoload-print-form (form) |
165 "Print FORM such that `make-docfile' will find the docstrings. | 192 "Print FORM such that `make-docfile' will find the docstrings. |
166 The variable `autoload-print-form-outbuf' specifies the buffer to | 193 The variable `autoload-print-form-outbuf' specifies the buffer to |
167 put the output in." | 194 put the output in." |
265 (done-any nil) | 292 (done-any nil) |
266 (visited (get-file-buffer file)) | 293 (visited (get-file-buffer file)) |
267 output-end) | 294 output-end) |
268 | 295 |
269 ;; If the autoload section we create here uses an absolute | 296 ;; If the autoload section we create here uses an absolute |
270 ;; pathname for FILE in its header, and then Emacs is installed | 297 ;; file name for FILE in its header, and then Emacs is installed |
271 ;; under a different path on another system, | 298 ;; under a different path on another system, |
272 ;; `update-autoloads-here' won't be able to find the files to be | 299 ;; `update-autoloads-here' won't be able to find the files to be |
273 ;; autoloaded. So, if FILE is in the same directory or a | 300 ;; autoloaded. So, if FILE is in the same directory or a |
274 ;; subdirectory of the current buffer's directory, we'll make it | 301 ;; subdirectory of the current buffer's directory, we'll make it |
275 ;; relative to the current buffer's directory. | 302 ;; relative to the current buffer's directory. |
352 (goto-char output-end) | 379 (goto-char output-end) |
353 (insert generate-autoload-section-trailer))) | 380 (insert generate-autoload-section-trailer))) |
354 (message "Generating autoloads for %s...done" file))) | 381 (message "Generating autoloads for %s...done" file))) |
355 | 382 |
356 ;;;###autoload | 383 ;;;###autoload |
357 (defun update-file-autoloads (file) | 384 (defun update-file-autoloads (file &optional save-after) |
358 "Update the autoloads for FILE in `generated-autoload-file' | 385 "Update the autoloads for FILE in `generated-autoload-file' |
359 \(which FILE might bind in its local variables). | 386 \(which FILE might bind in its local variables). |
360 Return FILE if there was no autoload cookie in it." | 387 If SAVE-AFTER is non-nil (which is always, when called interactively), |
361 (interactive "fUpdate autoloads for file: ") | 388 save the buffer too. |
389 | |
390 Return FILE if there was no autoload cookie in it, else nil." | |
391 (interactive "fUpdate autoloads for file: \np") | |
362 (let ((load-name (let ((name (file-name-nondirectory file))) | 392 (let ((load-name (let ((name (file-name-nondirectory file))) |
363 (if (string-match "\\.elc?\\(\\.\\|$\\)" name) | 393 (if (string-match "\\.elc?\\(\\.\\|$\\)" name) |
364 (substring name 0 (match-beginning 0)) | 394 (substring name 0 (match-beginning 0)) |
365 name))) | 395 name))) |
366 (found nil) | 396 (found nil) |
401 (last-time (nth 4 form)) | 431 (last-time (nth 4 form)) |
402 (file-time (nth 5 (file-attributes file)))) | 432 (file-time (nth 5 (file-attributes file)))) |
403 (if (and (or (null existing-buffer) | 433 (if (and (or (null existing-buffer) |
404 (not (buffer-modified-p existing-buffer))) | 434 (not (buffer-modified-p existing-buffer))) |
405 (listp last-time) (= (length last-time) 2) | 435 (listp last-time) (= (length last-time) 2) |
406 (not (autoload-before-p last-time file-time))) | 436 (not (time-less-p last-time file-time))) |
407 (progn | 437 (progn |
408 (if (interactive-p) | 438 (if (interactive-p) |
409 (message "\ | 439 (message "\ |
410 Autoload section for %s is up to date." | 440 Autoload section for %s is up to date." |
411 file)) | 441 file)) |
456 (setq no-autoloads t) | 486 (setq no-autoloads t) |
457 t) | 487 t) |
458 (or existing-buffer | 488 (or existing-buffer |
459 (kill-buffer (current-buffer)))))))) | 489 (kill-buffer (current-buffer)))))))) |
460 (generate-file-autoloads file)))) | 490 (generate-file-autoloads file)))) |
461 (and (interactive-p) | 491 (and save-after |
462 (buffer-modified-p) | 492 (buffer-modified-p) |
463 (save-buffer)) | 493 (save-buffer)) |
464 | 494 |
465 (if no-autoloads file)))) | 495 (if no-autoloads file)))) |
466 | |
467 (defun autoload-before-p (time1 time2) | |
468 (or (< (car time1) (car time2)) | |
469 (and (= (car time1) (car time2)) | |
470 (< (nth 1 time1) (nth 1 time2))))) | |
471 | 496 |
472 (defun autoload-remove-section (begin) | 497 (defun autoload-remove-section (begin) |
473 (goto-char begin) | 498 (goto-char begin) |
474 (search-forward generate-autoload-section-trailer) | 499 (search-forward generate-autoload-section-trailer) |
475 (delete-region begin (point))) | 500 (delete-region begin (point))) |
476 | 501 |
477 ;;;###autoload | 502 ;;;###autoload |
478 (defun update-autoloads-from-directories (&rest dirs) | 503 (defun update-directory-autoloads (&rest dirs) |
479 "\ | 504 "\ |
480 Update loaddefs.el with all the current autoloads from DIRS, and no old ones. | 505 Update loaddefs.el with all the current autoloads from DIRS, and no old ones. |
481 This uses `update-file-autoloads' (which see) do its work." | 506 This uses `update-file-autoloads' (which see) to do its work. |
507 In an interactive call, you must give one argument, the name | |
508 of a single directory. In a call from Lisp, you can supply multiple | |
509 directories as separate arguments, but this usage is discouraged. | |
510 | |
511 The function does NOT recursively descend into subdirectories of the | |
512 directory or directories specified." | |
482 (interactive "DUpdate autoloads from directory: ") | 513 (interactive "DUpdate autoloads from directory: ") |
483 (let* ((files-re (let ((tmp nil)) | 514 (let* ((files-re (let ((tmp nil)) |
484 (dolist (suf load-suffixes | 515 (dolist (suf load-suffixes |
485 (concat "^[^=.].*" (regexp-opt tmp t) "\\'")) | 516 (concat "^[^=.].*" (regexp-opt tmp t) "\\'")) |
486 (unless (string-match "\\.elc" suf) (push suf tmp))))) | 517 (unless (string-match "\\.elc" suf) (push suf tmp))))) |
515 (autoload-remove-section (match-beginning 0)) | 546 (autoload-remove-section (match-beginning 0)) |
516 (let ((last-time (nth 4 form))) | 547 (let ((last-time (nth 4 form))) |
517 (dolist (file file) | 548 (dolist (file file) |
518 (let ((file-time (nth 5 (file-attributes file)))) | 549 (let ((file-time (nth 5 (file-attributes file)))) |
519 (when (and file-time | 550 (when (and file-time |
520 (not (autoload-before-p last-time | 551 (not (time-less-p last-time file-time))) |
521 file-time))) | |
522 ;; file unchanged | 552 ;; file unchanged |
523 (push file no-autoloads) | 553 (push file no-autoloads) |
524 (setq files (delete file files))))))) | 554 (setq files (delete file files))))))) |
525 ((not (stringp file))) | 555 ((not (stringp file))) |
526 ((not (file-exists-p (expand-file-name file top-dir))) | 556 ((not (file-exists-p (expand-file-name file top-dir))) |
546 (current-buffer) nil nil no-autoloads this-time) | 576 (current-buffer) nil nil no-autoloads this-time) |
547 (insert generate-autoload-section-trailer)) | 577 (insert generate-autoload-section-trailer)) |
548 | 578 |
549 (save-buffer)))) | 579 (save-buffer)))) |
550 | 580 |
581 (define-obsolete-function-alias 'update-autoloads-from-directories | |
582 'update-directory-autoloads "22.1") | |
583 | |
551 ;;;###autoload | 584 ;;;###autoload |
552 (defun batch-update-autoloads () | 585 (defun batch-update-autoloads () |
553 "Update loaddefs.el autoloads in batch mode. | 586 "Update loaddefs.el autoloads in batch mode. |
554 Calls `update-autoloads-from-directories' on the command line arguments." | 587 Calls `update-directory-autoloads' on the command line arguments." |
555 (apply 'update-autoloads-from-directories command-line-args-left) | 588 (apply 'update-directory-autoloads command-line-args-left) |
556 (setq command-line-args-left nil)) | 589 (setq command-line-args-left nil)) |
557 | 590 |
558 (provide 'autoload) | 591 (provide 'autoload) |
559 | 592 |
593 ;; arch-tag: 00244766-98f4-4767-bf42-8a22103441c6 | |
560 ;;; autoload.el ends here | 594 ;;; autoload.el ends here |