X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/9ed4d64fd35fdcb7f177947df309c5a51ae13402..bec34fb05face8154d5dd5fc86d4442ff82c3843:/lisp/emacs-lisp/autoload.el diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index d54837374d..5a5eb55a2a 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el @@ -1,54 +1,46 @@ -;;; autoload.el --- maintain autoloads in loaddefs.el. +;; autoload.el --- maintain autoloads in loaddefs.el -;;; Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. -;;; -;; Author: Roland McGrath +;; Copyright (C) 1991,92,93,94,95,96,97, 2001,02,03,04 +;; Free Software Foundation, Inc. + +;; Author: Roland McGrath ;; Keywords: maint -;;; This program is free software; you can redistribute it and/or modify -;;; it under the terms of the GNU General Public License as published by -;;; the Free Software Foundation; either version 2, or (at your option) -;;; any later version. -;;; -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;; GNU General Public License for more details. -;;; -;;; A copy of the GNU General Public License can be obtained from this -;;; program's author (send electronic mail to roland@ai.mit.edu) or from -;;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA -;;; 02139, USA. -;;; - -;;; Commentary;: - -;; This code helps GNU Emacs maintainers keep the autoload.el file up to +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This code helps GNU Emacs maintainers keep the loaddefs.el file up to ;; date. It interprets magic cookies of the form ";;;###autoload" in ;; lisp source files in various useful ways. To learn more, read the ;; source; if you're going to use this, you'd better be able to. ;;; Code: -(defun make-autoload (form file) - "Turn FORM, a defun or defmacro, into an autoload for source file FILE. -Returns nil if FORM is not a defun or defmacro." - (let ((car (car-safe form))) - (if (memq car '(defun defmacro)) - (let ((macrop (eq car 'defmacro)) - name doc) - (setq form (cdr form)) - (setq name (car form)) - ;; Ignore the arguments. - (setq form (cdr (cdr form))) - (setq doc (car form)) - (if (stringp doc) - (setq form (cdr form)) - (setq doc nil)) - (list 'autoload (list 'quote name) file doc - (eq (car-safe (car form)) 'interactive) - (if macrop (list 'quote 'macro) nil))) - nil))) +(require 'lisp-mode) ;for `doc-string-elt' properties. +(require 'help-fns) ;for help-add-fundoc-usage. +(eval-when-compile (require 'cl)) + +(defvar generated-autoload-file "loaddefs.el" + "*File \\[update-file-autoloads] puts autoloads into. +A `.el' file can set this in its local variables section to make its +autoloads go somewhere else. The autoload file is assumed to contain a +trailer starting with a FormFeed character.") (defconst generate-autoload-cookie ";;;###autoload" "Magic comment indicating the following form should be autoloaded. @@ -65,43 +57,200 @@ read and an autoload made for it. If there is further text on the line, that text will be copied verbatim to `generated-autoload-file'.") (defconst generate-autoload-section-header "\f\n;;;### " - "String inserted before the form identifying -the section of autoloads for a file.") + "String that marks the form at the start of a new file's autoload section.") (defconst generate-autoload-section-trailer "\n;;;***\n" "String which indicates the end of the section of autoloads for a file.") -;;; Forms which have doc-strings which should be printed specially. -;;; A doc-string-elt property of ELT says that (nth ELT FORM) is -;;; the doc-string in FORM. -;;; -;;; There used to be the following note here: -;;; ;;; Note: defconst and defvar should NOT be marked in this way. -;;; ;;; We don't want to produce defconsts and defvars that -;;; ;;; make-docfile can grok, because then it would grok them twice, -;;; ;;; once in foo.el (where they are given with ;;;###autoload) and -;;; ;;; once in loaddefs.el. -;;; -;;; Counter-note: Yes, they should be marked in this way. -;;; make-docfile only processes those files that are loaded into the -;;; dumped Emacs, and those files should never have anything -;;; autoloaded here. The above-feared problem only occurs with files -;;; which have autoloaded entries *and* are processed by make-docfile; -;;; there should be no such files. - -(put 'autoload 'doc-string-elt 3) -(put 'defun 'doc-string-elt 3) -(put 'defvar 'doc-string-elt 3) -(put 'defconst 'doc-string-elt 3) -(put 'defmacro 'doc-string-elt 3) +(defconst generate-autoload-section-continuation ";;;;;; " + "String to add on each continuation of the section header form.") + +(defun make-autoload (form file) + "Turn FORM into an autoload or defvar for source file FILE. +Returns nil if FORM is not a special autoload form (i.e. a function definition +or macro definition or a defcustom)." + (let ((car (car-safe form)) expand) + (cond + ;; For complex cases, try again on the macro-expansion. + ((and (memq car '(easy-mmode-define-global-mode + easy-mmode-define-minor-mode define-minor-mode)) + (setq expand (let ((load-file-name file)) (macroexpand form))) + (eq (car expand) 'progn) + (memq :autoload-end expand)) + (let ((end (memq :autoload-end expand))) + ;; Cut-off anything after the :autoload-end marker. + (setcdr end nil) + (cons 'progn + (mapcar (lambda (form) (make-autoload form file)) + (cdr expand))))) + + ;; For special function-like operators, use the `autoload' function. + ((memq car '(defun define-skeleton defmacro define-derived-mode + define-compilation-mode + define-generic-mode easy-mmode-define-minor-mode + easy-mmode-define-global-mode + define-minor-mode defun* defmacro*)) + (let* ((macrop (memq car '(defmacro defmacro*))) + (name (nth 1 form)) + (args (case car + ((defun defmacro defun* defmacro*) (nth 2 form)) + ((define-skeleton) '(&optional str arg)) + ((define-generic-mode define-derived-mode + define-compilation-mode) nil) + (t))) + (body (nthcdr (get car 'doc-string-elt) form)) + (doc (if (stringp (car body)) (pop body)))) + (when (listp args) + ;; Add the usage form at the end where describe-function-1 + ;; can recover it. + (setq doc (help-add-fundoc-usage doc args))) + ;; `define-generic-mode' quotes the name, so take care of that + (list 'autoload (if (listp name) name (list 'quote name)) file doc + (or (and (memq car '(define-skeleton define-derived-mode + define-generic-mode + easy-mmode-define-global-mode + easy-mmode-define-minor-mode + define-minor-mode)) t) + (eq (car-safe (car body)) 'interactive)) + (if macrop (list 'quote 'macro) nil)))) + + ;; Convert defcustom to less space-consuming data. + ((eq car 'defcustom) + (let ((varname (car-safe (cdr-safe form))) + (init (car-safe (cdr-safe (cdr-safe form)))) + (doc (car-safe (cdr-safe (cdr-safe (cdr-safe form))))) + ;; (rest (cdr-safe (cdr-safe (cdr-safe (cdr-safe form))))) + ) + `(progn + (defvar ,varname ,init ,doc) + (custom-autoload ',varname ,file)))) + + ;; nil here indicates that this is not a special autoload form. + (t nil)))) + +;; Forms which have doc-strings which should be printed specially. +;; A doc-string-elt property of ELT says that (nth ELT FORM) is +;; the doc-string in FORM. +;; Those properties are now set in lisp-mode.el. + (defun autoload-trim-file-name (file) - ;; Returns a relative pathname of FILE including the last directory. + ;; Returns a relative pathname of FILE + ;; starting from the directory that loaddefs.el is in. + ;; That is normally a directory in load-path, + ;; which means Emacs will be able to find FILE when it looks. + ;; Any extra directory names here would prevent finding the file. (setq file (expand-file-name file)) (file-relative-name file - (file-name-directory - (directory-file-name - (file-name-directory file))))) + (file-name-directory generated-autoload-file))) + +(defun autoload-read-section-header () + "Read a section header form. +Since continuation lines have been marked as comments, +we must copy the text of the form and remove those comment +markers before we call `read'." + (save-match-data + (let ((beginning (point)) + string) + (forward-line 1) + (while (looking-at generate-autoload-section-continuation) + (forward-line 1)) + (setq string (buffer-substring beginning (point))) + (with-current-buffer (get-buffer-create " *autoload*") + (erase-buffer) + (insert string) + (goto-char (point-min)) + (while (search-forward generate-autoload-section-continuation nil t) + (replace-match " ")) + (goto-char (point-min)) + (read (current-buffer)))))) + +(defvar autoload-print-form-outbuf) + +(defun autoload-print-form (form) + "Print FORM such that `make-docfile' will find the docstrings. +The variable `autoload-print-form-outbuf' specifies the buffer to +put the output in." + (cond + ;; If the form is a sequence, recurse. + ((eq (car form) 'progn) (mapcar 'autoload-print-form (cdr form))) + ;; Symbols at the toplevel are meaningless. + ((symbolp form) nil) + (t + (let ((doc-string-elt (get (car-safe form) 'doc-string-elt)) + (outbuf autoload-print-form-outbuf)) + (if (and doc-string-elt (stringp (nth doc-string-elt form))) + ;; We need to hack the printing because the + ;; doc-string must be printed specially for + ;; make-docfile (sigh). + (let* ((p (nthcdr (1- doc-string-elt) form)) + (elt (cdr p))) + (setcdr p nil) + (princ "\n(" outbuf) + (let ((print-escape-newlines t) + (print-escape-nonascii t)) + (dolist (elt form) + (prin1 elt outbuf) + (princ " " outbuf))) + (princ "\"\\\n" outbuf) + (let ((begin (with-current-buffer outbuf (point)))) + (princ (substring (prin1-to-string (car elt)) 1) + outbuf) + ;; Insert a backslash before each ( that + ;; appears at the beginning of a line in + ;; the doc string. + (with-current-buffer outbuf + (save-excursion + (while (re-search-backward "\n[[(]" begin t) + (forward-char 1) + (insert "\\")))) + (if (null (cdr elt)) + (princ ")" outbuf) + (princ " " outbuf) + (princ (substring (prin1-to-string (cdr elt)) 1) + outbuf)) + (terpri outbuf))) + (let ((print-escape-newlines t) + (print-escape-nonascii t)) + (print form outbuf))))))) + +(defun autoload-ensure-default-file (file) + "Make sure that the autoload file FILE exists and if not create it." + (unless (file-exists-p file) + (write-region + (concat ";;; " (file-name-nondirectory file) + " --- automatically extracted autoloads\n" + ";;\n" + ";;; Code:\n\n" + " \n;; Local Variables:\n" + ";; version-control: never\n" + ";; no-byte-compile: t\n" + ";; no-update-autoloads: t\n" + ";; End:\n" + ";;; " (file-name-nondirectory file) + " ends here\n") + nil file)) + file) + +(defun autoload-insert-section-header (outbuf autoloads load-name file time) + "Insert the section-header line, +which lists the file name and which functions are in it, etc." + (insert generate-autoload-section-header) + (prin1 (list 'autoloads autoloads load-name + (if (stringp file) (autoload-trim-file-name file) file) + time) + outbuf) + (terpri outbuf) + ;; Break that line at spaces, to avoid very long lines. + ;; Make each sub-line into a comment. + (with-current-buffer outbuf + (save-excursion + (forward-line -1) + (while (not (eolp)) + (move-to-column 64) + (skip-chars-forward "^ \n") + (or (eolp) + (insert "\n" generate-autoload-section-continuation)))))) (defun generate-file-autoloads (file) "Insert at point a loaddefs autoload section for FILE. @@ -113,7 +262,7 @@ are used." (let ((outbuf (current-buffer)) (autoloads-done '()) (load-name (let ((name (file-name-nondirectory file))) - (if (string-match "\\.elc?$" name) + (if (string-match "\\.elc?\\(\\.\\|$\\)" name) (substring name 0 (match-beginning 0)) name))) (print-length nil) @@ -143,7 +292,16 @@ are used." (save-excursion (unwind-protect (progn - (set-buffer (find-file-noselect file)) + (if visited + (set-buffer visited) + ;; It is faster to avoid visiting the file. + (set-buffer (get-buffer-create " *generate-autoload-file*")) + (kill-all-local-variables) + (erase-buffer) + (setq buffer-undo-list t + buffer-read-only nil) + (emacs-lisp-mode) + (insert-file-contents file nil)) (save-excursion (save-restriction (widen) @@ -158,59 +316,26 @@ are used." (if (eolp) ;; Read the next form and make an autoload. (let* ((form (prog1 (read (current-buffer)) - (forward-line 1))) - (autoload (make-autoload form load-name)) - (doc-string-elt (get (car-safe form) - 'doc-string-elt))) + (or (bolp) (forward-line 1)))) + (autoload (make-autoload form load-name))) (if autoload (setq autoloads-done (cons (nth 1 form) autoloads-done)) (setq autoload form)) - (if (and doc-string-elt - (stringp (nth doc-string-elt autoload))) - ;; We need to hack the printing because the - ;; doc-string must be printed specially for - ;; make-docfile (sigh). - (let* ((p (nthcdr (1- doc-string-elt) - autoload)) - (elt (cdr p))) - (setcdr p nil) - (princ "\n(" outbuf) - (let ((print-escape-newlines t)) - (mapcar (function (lambda (elt) - (prin1 elt outbuf) - (princ " " outbuf))) - autoload)) - (princ "\"\\\n" outbuf) - (let ((begin (save-excursion - (set-buffer outbuf) - (point)))) - (princ (substring - (prin1-to-string (car elt)) 1) - outbuf) - ;; Insert a backslash before each ( that - ;; appears at the beginning of a line in - ;; the doc string. - (save-excursion - (set-buffer outbuf) - (save-excursion - (while (search-backward "\n(" begin t) - (forward-char 1) - (insert "\\")))) - (if (null (cdr elt)) - (princ ")" outbuf) - (princ " " outbuf) - (princ (substring - (prin1-to-string (cdr elt)) - 1) - outbuf)) - (terpri outbuf))) - (let ((print-escape-newlines t)) - (print autoload outbuf))) - ;; Copy the rest of the line to the output. - (let ((begin (point))) - (forward-line 1) - (princ (buffer-substring begin (point)) outbuf))))) + (let ((autoload-print-form-outbuf outbuf)) + (autoload-print-form autoload))) + + ;; Copy the rest of the line to the output. + (princ (buffer-substring + (progn + ;; Back up over whitespace, to preserve it. + (skip-chars-backward " \f\t") + (if (= (char-after (1+ (point))) ? ) + ;; Eat one space. + (forward-char 1)) + (point)) + (progn (forward-line 1) (point))) + outbuf))) ((looking-at ";") ;; Don't read the comment. (forward-line 1)) @@ -224,39 +349,49 @@ are used." (setq output-end (point-marker)))) (if done-any (progn - (insert generate-autoload-section-header) - (prin1 (list 'autoloads autoloads-done load-name - (autoload-trim-file-name file) - (nth 5 (file-attributes file))) - outbuf) - (terpri outbuf) + ;; Insert the section-header line + ;; which lists the file name and which functions are in it, etc. + (autoload-insert-section-header outbuf autoloads-done load-name file + (nth 5 (file-attributes file))) (insert ";;; Generated autoloads from " (autoload-trim-file-name file) "\n") (goto-char output-end) (insert generate-autoload-section-trailer))) (message "Generating autoloads for %s...done" file))) -(defconst generated-autoload-file "loaddefs.el" - "*File \\[update-file-autoloads] puts autoloads into. -A .el file can set this in its local variables section to make its -autoloads go somewhere else.") - ;;;###autoload (defun update-file-autoloads (file) "Update the autoloads for FILE in `generated-autoload-file' -\(which FILE might bind in its local variables)." +\(which FILE might bind in its local variables). +Return FILE if there was no autoload cookie in it." (interactive "fUpdate autoloads for file: ") (let ((load-name (let ((name (file-name-nondirectory file))) - (if (string-match "\\.elc?$" name) + (if (string-match "\\.elc?\\(\\.\\|$\\)" name) (substring name 0 (match-beginning 0)) name))) (found nil) - (existing-buffer (get-file-buffer file))) + (existing-buffer (get-file-buffer file)) + (no-autoloads nil)) (save-excursion ;; We want to get a value for generated-autoload-file from ;; the local variables section if it's there. - (set-buffer (find-file-noselect file)) - (set-buffer (find-file-noselect generated-autoload-file)) + (if existing-buffer + (set-buffer existing-buffer)) + ;; We must read/write the file without any code conversion, + ;; but still decode EOLs. + (let ((coding-system-for-read 'raw-text)) + (set-buffer (find-file-noselect + (autoload-ensure-default-file + (expand-file-name generated-autoload-file + (expand-file-name "lisp" + source-directory))))) + ;; This is to make generated-autoload-file have Unix EOLs, so + ;; that it is portable to all platforms. + (setq buffer-file-coding-system 'raw-text-unix)) + (or (> (buffer-size) 0) + (error "Autoloads file %s does not exist" buffer-file-name)) + (or (file-writable-p buffer-file-name) + (error "Autoloads file %s is not writable" buffer-file-name)) (save-excursion (save-restriction (widen) @@ -264,9 +399,7 @@ autoloads go somewhere else.") ;; Look for the section for LOAD-NAME. (while (and (not found) (search-forward generate-autoload-section-header nil t)) - (let ((form (condition-case () - (read (current-buffer)) - (end-of-file nil)))) + (let ((form (autoload-read-section-header))) (cond ((string= (nth 2 form) load-name) ;; We found the section for this file. ;; Check if it is up to date. @@ -276,13 +409,12 @@ autoloads go somewhere else.") (if (and (or (null existing-buffer) (not (buffer-modified-p existing-buffer))) (listp last-time) (= (length last-time) 2) - (or (> (car last-time) (car file-time)) - (and (= (car last-time) (car file-time)) - (>= (nth 1 last-time) - (nth 1 file-time))))) + (not (time-less-p last-time file-time))) (progn - (message "Autoload section for %s is up to date." - file) + (if (interactive-p) + (message "\ +Autoload section for %s is up to date." + file)) (setq found 'up-to-date)) (search-forward generate-autoload-section-trailer) (delete-region begin (point)) @@ -294,111 +426,142 @@ autoloads go somewhere else.") ;; insert one before the section here. (goto-char (match-beginning 0)) (setq found 'new))))) + (or found + (progn + (setq found 'new) + ;; No later sections in the file. Put before the last page. + (goto-char (point-max)) + (search-backward "\f" nil t))) (or (eq found 'up-to-date) (and (eq found 'new) ;; Check that FILE has any cookies before generating a ;; new section for it. (save-excursion - (set-buffer (find-file-noselect file)) + (if existing-buffer + (set-buffer existing-buffer) + ;; It is faster to avoid visiting the file. + (set-buffer (get-buffer-create " *autoload-file*")) + (kill-all-local-variables) + (erase-buffer) + (setq buffer-undo-list t + buffer-read-only nil) + (emacs-lisp-mode) + (insert-file-contents file nil)) (save-excursion - (widen) - (goto-char (point-min)) - (if (search-forward (concat "\n" - generate-autoload-cookie) - nil t) - nil - (if (interactive-p) - (message file " has no autoloads")) - t)))) - (generate-file-autoloads file)) - (setq done t))) - (if (interactive-p) (save-buffer)) - (if (and (null existing-buffer) - (setq existing-buffer (get-file-buffer file))) - (kill-buffer existing-buffer))))) + (save-restriction + (widen) + (goto-char (point-min)) + (prog1 + (if (re-search-forward + (concat "^" (regexp-quote + generate-autoload-cookie)) + nil t) + nil + (if (interactive-p) + (message "%s has no autoloads" file)) + (setq no-autoloads t) + t) + (or existing-buffer + (kill-buffer (current-buffer)))))))) + (generate-file-autoloads file)))) + (and (interactive-p) + (buffer-modified-p) + (save-buffer)) + + (if no-autoloads file)))) + +(defun autoload-remove-section (begin) + (goto-char begin) + (search-forward generate-autoload-section-trailer) + (delete-region begin (point))) ;;;###autoload -(defun update-autoloads-here () +(defun update-directory-autoloads (&rest dirs) "\ -Update sections of the current buffer generated by \\[update-file-autoloads]." - (interactive) - (let ((generated-autoload-file (buffer-file-name))) - (save-excursion - (goto-char (point-min)) - (while (search-forward generate-autoload-section-header nil t) - (let* ((form (condition-case () - (read (current-buffer)) - (end-of-file nil))) - (file (nth 3 form))) - (if (and (stringp file) - (or (get-file-buffer file) - (file-exists-p file))) - () - (setq file (if (y-or-n-p (format "Library \"%s\" (load \ -file \"%s\") doesn't exist. Remove its autoload section? " - (nth 2 form) file)) - t - (condition-case () - (read-file-name (format "Find \"%s\" load file: " - (nth 2 form)) - nil nil t) - (quit nil))))) - (if file - (let ((begin (match-beginning 0))) - (search-forward generate-autoload-section-trailer) - (delete-region begin (point)))) - (if (stringp file) - (generate-file-autoloads file))))))) +Update loaddefs.el with all the current autoloads from DIRS, and no old ones. +This uses `update-file-autoloads' (which see) do its work. +In an interactive call, you must give one argument, the name +of a single directory. In a call from Lisp, you can supply multiple +directories as separate arguments, but this usage is discouraged. -;;;###autoload -(defun update-directory-autoloads (dir) - "Run \\[update-file-autoloads] on each .el file in DIR." - (interactive "DUpdate autoloads for directory: ") - (mapcar 'update-file-autoloads - (directory-files dir t "\\.el$")) - (if (interactive-p) +The function does NOT recursively descend into subdirectories of the +directory or directories specified." + (interactive "DUpdate autoloads from directory: ") + (let* ((files-re (let ((tmp nil)) + (dolist (suf load-suffixes + (concat "^[^=.].*" (regexp-opt tmp t) "\\'")) + (unless (string-match "\\.elc" suf) (push suf tmp))))) + (files (apply 'nconc + (mapcar (lambda (dir) + (directory-files (expand-file-name dir) + t files-re)) + dirs))) + (this-time (current-time)) + (no-autoloads nil) ;files with no autoload cookies. + (autoloads-file + (expand-file-name generated-autoload-file + (expand-file-name "lisp" source-directory))) + (top-dir (file-name-directory autoloads-file))) + + (with-current-buffer + (find-file-noselect (autoload-ensure-default-file autoloads-file)) (save-excursion - (set-buffer (find-file-noselect generated-autoload-file)) - (save-buffer)))) + + ;; Canonicalize file names and remove the autoload file itself. + (setq files (delete (autoload-trim-file-name buffer-file-name) + (mapcar 'autoload-trim-file-name files))) + + (goto-char (point-min)) + (while (search-forward generate-autoload-section-header nil t) + (let* ((form (autoload-read-section-header)) + (file (nth 3 form))) + (cond ((and (consp file) (stringp (car file))) + ;; This is a list of files that have no autoload cookies. + ;; There shouldn't be more than one such entry. + ;; Remove the obsolete section. + (autoload-remove-section (match-beginning 0)) + (let ((last-time (nth 4 form))) + (dolist (file file) + (let ((file-time (nth 5 (file-attributes file)))) + (when (and file-time + (not (time-less-p last-time file-time))) + ;; file unchanged + (push file no-autoloads) + (setq files (delete file files))))))) + ((not (stringp file))) + ((not (file-exists-p (expand-file-name file top-dir))) + ;; Remove the obsolete section. + (autoload-remove-section (match-beginning 0))) + ((equal (nth 4 form) (nth 5 (file-attributes file))) + ;; File hasn't changed. + nil) + (t + (update-file-autoloads file))) + (setq files (delete file files))))) + ;; Elements remaining in FILES have no existing autoload sections yet. + (setq no-autoloads + (append no-autoloads + (delq nil (mapcar 'update-file-autoloads files)))) + (when no-autoloads + ;; Sort them for better readability. + (setq no-autoloads (sort no-autoloads 'string<)) + ;; Add the `no-autoloads' section. + (goto-char (point-max)) + (search-backward "\f" nil t) + (autoload-insert-section-header + (current-buffer) nil nil no-autoloads this-time) + (insert generate-autoload-section-trailer)) + + (save-buffer)))) ;;;###autoload (defun batch-update-autoloads () - "Update the autoloads for the files or directories on the command line. -Runs \\[update-file-autoloads] on files and \\[update-directory-autoloads] -on directories. Must be used only with -batch, and kills Emacs on completion. -Each file will be processed even if an error occurred previously. -For example, invoke \"emacs -batch -f batch-update-autoloads *.el\"" - (if (not noninteractive) - (error "batch-update-autoloads is to be used only with -batch")) - (let ((lost nil) - (args command-line-args-left) - (enable-local-eval nil)) ;Don't query in batch mode. - (message "Updating autoloads in %s..." generated-autoload-file) - (let ((frob (function - (lambda (file) - (condition-case lossage - (update-file-autoloads file) - (error - (princ ">>Error processing ") - (princ file) - (princ ": ") - (if (fboundp 'display-error) - (display-error lossage nil) - (prin1 lossage)) - (princ "\n") - (setq lost t))))))) - (while args - (if (file-directory-p (expand-file-name (car args))) - (let ((rest (directory-files (car args) t "\\.el$"))) - (while rest - (funcall frob (car rest)) - (setq rest (cdr rest)))) - (funcall frob (car args))) - (setq args (cdr args)))) - (save-some-buffers t) - (message "Done") - (kill-emacs (if lost 1 0)))) + "Update loaddefs.el autoloads in batch mode. +Calls `update-directory-autoloads' on the command line arguments." + (apply 'update-directory-autoloads command-line-args-left) + (setq command-line-args-left nil)) (provide 'autoload) +;;; arch-tag: 00244766-98f4-4767-bf42-8a22103441c6 ;;; autoload.el ends here