Mercurial > emacs
comparison lisp/emacs-lisp/autoload.el @ 90979:988f1edc9674
Merge from emacs--devo--0
Patches applied:
* emacs--devo--0 (patch 803-805)
- Update from CVS
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-227
author | Miles Bader <miles@gnu.org> |
---|---|
date | Mon, 09 Jul 2007 08:00:55 +0000 |
parents | 03ec96a627ba 6416cbdef0fa |
children | a66921565bcb |
comparison
equal
deleted
inserted
replaced
90978:f866074aedc4 | 90979:988f1edc9674 |
---|---|
39 (defvar generated-autoload-file "loaddefs.el" | 39 (defvar generated-autoload-file "loaddefs.el" |
40 "*File \\[update-file-autoloads] puts autoloads into. | 40 "*File \\[update-file-autoloads] puts autoloads into. |
41 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 |
42 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 |
43 trailer starting with a FormFeed character.") | 43 trailer starting with a FormFeed character.") |
44 | 44 (put 'generated-autoload-file 'safe-local-variable 'stringp) |
45 (defconst generate-autoload-cookie ";;;###autoload" | 45 |
46 ;; This feels like it should be a defconst, but MH-E sets it to | |
47 ;; ";;;###mh-autoload" for the autoloads that are to go into mh-loaddefs.el. | |
48 (defvar generate-autoload-cookie ";;;###autoload" | |
46 "Magic comment indicating the following form should be autoloaded. | 49 "Magic comment indicating the following form should be autoloaded. |
47 Used by \\[update-file-autoloads]. This string should be | 50 Used by \\[update-file-autoloads]. This string should be |
48 meaningless to Lisp (e.g., a comment). | 51 meaningless to Lisp (e.g., a comment). |
49 | 52 |
50 This string is used: | 53 This string is used: |
51 | 54 |
52 ;;;###autoload | 55 \;;;###autoload |
53 \(defun function-to-be-autoloaded () ...) | 56 \(defun function-to-be-autoloaded () ...) |
54 | 57 |
55 If this string appears alone on a line, the following form will be | 58 If this string appears alone on a line, the following form will be |
56 read and an autoload made for it. If there is further text on the line, | 59 read and an autoload made for it. If there is further text on the line, |
57 that text will be copied verbatim to `generated-autoload-file'.") | 60 that text will be copied verbatim to `generated-autoload-file'.") |
62 (defconst generate-autoload-section-trailer "\n;;;***\n" | 65 (defconst generate-autoload-section-trailer "\n;;;***\n" |
63 "String which indicates the end of the section of autoloads for a file.") | 66 "String which indicates the end of the section of autoloads for a file.") |
64 | 67 |
65 (defconst generate-autoload-section-continuation ";;;;;; " | 68 (defconst generate-autoload-section-continuation ";;;;;; " |
66 "String to add on each continuation of the section header form.") | 69 "String to add on each continuation of the section header form.") |
70 | |
71 (defvar autoload-modified-buffers) ;Dynamically scoped var. | |
67 | 72 |
68 (defun make-autoload (form file) | 73 (defun make-autoload (form file) |
69 "Turn FORM into an autoload or defvar for source file FILE. | 74 "Turn FORM into an autoload or defvar for source file FILE. |
70 Returns nil if FORM is not a special autoload form (i.e. a function definition | 75 Returns nil if FORM is not a special autoload form (i.e. a function definition |
71 or macro definition or a defcustom)." | 76 or macro definition or a defcustom)." |
147 ;; Forms which have doc-strings which should be printed specially. | 152 ;; Forms which have doc-strings which should be printed specially. |
148 ;; A doc-string-elt property of ELT says that (nth ELT FORM) is | 153 ;; A doc-string-elt property of ELT says that (nth ELT FORM) is |
149 ;; the doc-string in FORM. | 154 ;; the doc-string in FORM. |
150 ;; Those properties are now set in lisp-mode.el. | 155 ;; Those properties are now set in lisp-mode.el. |
151 | 156 |
152 | 157 (defun autoload-generated-file () |
153 (defun autoload-trim-file-name (file) | 158 (expand-file-name generated-autoload-file |
154 ;; Returns a relative file path for FILE | 159 ;; File-local settings of generated-autoload-file should |
155 ;; starting from the directory that loaddefs.el is in. | 160 ;; be interpreted relative to the file's location, |
156 ;; That is normally a directory in load-path, | 161 ;; of course. |
157 ;; which means Emacs will be able to find FILE when it looks. | 162 (if (not (local-variable-p 'generated-autoload-file)) |
158 ;; Any extra directory names here would prevent finding the file. | 163 (expand-file-name "lisp" source-directory)))) |
159 (setq file (expand-file-name file)) | 164 |
160 (file-relative-name file | |
161 (file-name-directory generated-autoload-file))) | |
162 | 165 |
163 (defun autoload-read-section-header () | 166 (defun autoload-read-section-header () |
164 "Read a section header form. | 167 "Read a section header form. |
165 Since continuation lines have been marked as comments, | 168 Since continuation lines have been marked as comments, |
166 we must copy the text of the form and remove those comment | 169 we must copy the text of the form and remove those comment |
251 | 254 |
252 (defun autoload-insert-section-header (outbuf autoloads load-name file time) | 255 (defun autoload-insert-section-header (outbuf autoloads load-name file time) |
253 "Insert the section-header line, | 256 "Insert the section-header line, |
254 which lists the file name and which functions are in it, etc." | 257 which lists the file name and which functions are in it, etc." |
255 (insert generate-autoload-section-header) | 258 (insert generate-autoload-section-header) |
256 (prin1 (list 'autoloads autoloads load-name | 259 (prin1 (list 'autoloads autoloads load-name file time) |
257 (if (stringp file) (autoload-trim-file-name file) file) | |
258 time) | |
259 outbuf) | 260 outbuf) |
260 (terpri outbuf) | 261 (terpri outbuf) |
261 ;; Break that line at spaces, to avoid very long lines. | 262 ;; Break that line at spaces, to avoid very long lines. |
262 ;; Make each sub-line into a comment. | 263 ;; Make each sub-line into a comment. |
263 (with-current-buffer outbuf | 264 (with-current-buffer outbuf |
270 (insert "\n" generate-autoload-section-continuation)))))) | 271 (insert "\n" generate-autoload-section-continuation)))))) |
271 | 272 |
272 (defun autoload-find-file (file) | 273 (defun autoload-find-file (file) |
273 "Fetch file and put it in a temp buffer. Return the buffer." | 274 "Fetch file and put it in a temp buffer. Return the buffer." |
274 ;; It is faster to avoid visiting the file. | 275 ;; It is faster to avoid visiting the file. |
276 (setq file (expand-file-name file)) | |
275 (with-current-buffer (get-buffer-create " *autoload-file*") | 277 (with-current-buffer (get-buffer-create " *autoload-file*") |
276 (kill-all-local-variables) | 278 (kill-all-local-variables) |
277 (erase-buffer) | 279 (erase-buffer) |
278 (setq buffer-undo-list t | 280 (setq buffer-undo-list t |
279 buffer-read-only nil) | 281 buffer-read-only nil) |
280 (emacs-lisp-mode) | 282 (emacs-lisp-mode) |
283 (setq default-directory (file-name-directory file)) | |
281 (insert-file-contents file nil) | 284 (insert-file-contents file nil) |
282 (let ((enable-local-variables :safe)) | 285 (let ((enable-local-variables :safe)) |
283 (hack-local-variables)) | 286 (hack-local-variables)) |
284 (current-buffer))) | 287 (current-buffer))) |
285 | 288 |
286 (defvar no-update-autoloads nil | 289 (defvar no-update-autoloads nil |
287 "File local variable to prevent scanning this file for autoload cookies.") | 290 "File local variable to prevent scanning this file for autoload cookies.") |
291 | |
292 (defun autoload-file-load-name (file) | |
293 (let ((name (file-name-nondirectory file))) | |
294 (if (string-match "\\.elc?\\(\\.\\|\\'\\)" name) | |
295 (substring name 0 (match-beginning 0)) | |
296 name))) | |
288 | 297 |
289 (defun generate-file-autoloads (file) | 298 (defun generate-file-autoloads (file) |
290 "Insert at point a loaddefs autoload section for FILE. | 299 "Insert at point a loaddefs autoload section for FILE. |
291 Autoloads are generated for defuns and defmacros in FILE | 300 Autoloads are generated for defuns and defmacros in FILE |
292 marked by `generate-autoload-cookie' (which see). | 301 marked by `generate-autoload-cookie' (which see). |
293 If FILE is being visited in a buffer, the contents of the buffer | 302 If FILE is being visited in a buffer, the contents of the buffer |
294 are used. | 303 are used. |
295 Return non-nil in the case where no autoloads were added at point." | 304 Return non-nil in the case where no autoloads were added at point." |
296 (interactive "fGenerate autoloads for file: ") | 305 (interactive "fGenerate autoloads for file: ") |
297 (let ((outbuf (current-buffer)) | 306 (autoload-generate-file-autoloads file (current-buffer))) |
298 (autoloads-done '()) | 307 |
299 (load-name (let ((name (file-name-nondirectory file))) | 308 ;; When called from `generate-file-autoloads' we should ignore |
300 (if (string-match "\\.elc?\\(\\.\\|$\\)" name) | 309 ;; `generated-autoload-file' altogether. When called from |
301 (substring name 0 (match-beginning 0)) | 310 ;; `update-file-autoloads' we don't know `outbuf'. And when called from |
302 name))) | 311 ;; `update-directory-autoloads' it's in between: we know the default |
303 (print-length nil) | 312 ;; `outbuf' but we should obey any file-local setting of |
304 (print-readably t) ; This does something in Lucid Emacs. | 313 ;; `generated-autoload-file'. |
305 (float-output-format nil) | 314 (defun autoload-generate-file-autoloads (file &optional outbuf outfile) |
306 (done-any nil) | 315 "Insert an autoload section for FILE in the appropriate buffer. |
307 (visited (get-file-buffer file)) | 316 Autoloads are generated for defuns and defmacros in FILE |
308 output-start) | 317 marked by `generate-autoload-cookie' (which see). |
309 | 318 If FILE is being visited in a buffer, the contents of the buffer are used. |
310 ;; If the autoload section we create here uses an absolute | 319 OUTBUF is the buffer in which the autoload statements should be inserted. |
311 ;; file name for FILE in its header, and then Emacs is installed | 320 If OUTBUF is nil, it will be determined by `autoload-generated-file'. |
312 ;; under a different path on another system, | 321 |
313 ;; `update-autoloads-here' won't be able to find the files to be | 322 If provided, OUTFILE is expected to be the file name of OUTBUF. |
314 ;; autoloaded. So, if FILE is in the same directory or a | 323 If OUTFILE is non-nil and FILE specifies a `generated-autoload-file' |
315 ;; subdirectory of the current buffer's directory, we'll make it | 324 different from OUTFILE, then OUTBUF is ignored. |
316 ;; relative to the current buffer's directory. | 325 |
317 (setq file (expand-file-name file)) | 326 Return non-nil iff FILE adds no autoloads to OUTFILE |
318 (let* ((source-truename (file-truename file)) | 327 \(or OUTBUF if OUTFILE is nil)." |
319 (dir-truename (file-name-as-directory | 328 (catch 'done |
320 (file-truename default-directory))) | 329 (let ((autoloads-done '()) |
321 (len (length dir-truename))) | 330 (load-name (autoload-file-load-name file)) |
322 (if (and (< len (length source-truename)) | 331 (print-length nil) |
323 (string= dir-truename (substring source-truename 0 len))) | 332 (print-readably t) ; This does something in Lucid Emacs. |
324 (setq file (substring source-truename len)))) | 333 (float-output-format nil) |
325 | 334 (visited (get-file-buffer file)) |
326 (with-current-buffer (or visited | 335 (otherbuf nil) |
327 ;; It is faster to avoid visiting the file. | 336 (absfile (expand-file-name file)) |
328 (autoload-find-file file)) | 337 relfile |
329 ;; Obey the no-update-autoloads file local variable. | 338 ;; nil until we found a cookie. |
330 (unless no-update-autoloads | 339 output-start) |
331 (message "Generating autoloads for %s..." file) | 340 |
332 (setq output-start (with-current-buffer outbuf (point))) | 341 (with-current-buffer (or visited |
333 (save-excursion | 342 ;; It is faster to avoid visiting the file. |
334 (save-restriction | 343 (autoload-find-file file)) |
335 (widen) | 344 ;; Obey the no-update-autoloads file local variable. |
336 (goto-char (point-min)) | 345 (unless no-update-autoloads |
337 (while (not (eobp)) | 346 (message "Generating autoloads for %s..." file) |
338 (skip-chars-forward " \t\n\f") | 347 (save-excursion |
339 (cond | 348 (save-restriction |
340 ((looking-at (regexp-quote generate-autoload-cookie)) | 349 (widen) |
341 (search-forward generate-autoload-cookie) | 350 (goto-char (point-min)) |
342 (skip-chars-forward " \t") | 351 (while (not (eobp)) |
343 (setq done-any t) | 352 (skip-chars-forward " \t\n\f") |
344 (if (eolp) | 353 (cond |
345 ;; Read the next form and make an autoload. | 354 ((looking-at (regexp-quote generate-autoload-cookie)) |
346 (let* ((form (prog1 (read (current-buffer)) | 355 ;; If not done yet, figure out where to insert this text. |
347 (or (bolp) (forward-line 1)))) | 356 (unless output-start |
348 (autoload (make-autoload form load-name))) | 357 (when (and outfile |
349 (if autoload | 358 (not (equal outfile (autoload-generated-file)))) |
350 (push (nth 1 form) autoloads-done) | 359 ;; A file-local setting of autoload-generated-file says |
351 (setq autoload form)) | 360 ;; we should ignore OUTBUF. |
352 (let ((autoload-print-form-outbuf outbuf)) | 361 (setq outbuf nil) |
353 (autoload-print-form autoload))) | 362 (setq otherbuf t)) |
354 | 363 (unless outbuf |
355 ;; Copy the rest of the line to the output. | 364 (setq outbuf (autoload-find-destination absfile)) |
356 (princ (buffer-substring | 365 (unless outbuf |
357 (progn | 366 ;; The file has autoload cookies, but they're |
358 ;; Back up over whitespace, to preserve it. | 367 ;; already up-to-date. If OUTFILE is nil, the |
359 (skip-chars-backward " \f\t") | 368 ;; entries are in the expected OUTBUF, otherwise |
360 (if (= (char-after (1+ (point))) ? ) | 369 ;; they're elsewhere. |
361 ;; Eat one space. | 370 (throw 'done outfile))) |
362 (forward-char 1)) | 371 (with-current-buffer outbuf |
363 (point)) | 372 (setq relfile (file-relative-name absfile)) |
364 (progn (forward-line 1) (point))) | 373 (setq output-start (point))) |
365 outbuf))) | 374 ;; (message "file=%S, relfile=%S, dest=%S" |
366 ((looking-at ";") | 375 ;; file relfile (autoload-generated-file)) |
367 ;; Don't read the comment. | 376 ) |
368 (forward-line 1)) | 377 (search-forward generate-autoload-cookie) |
369 (t | 378 (skip-chars-forward " \t") |
370 (forward-sexp 1) | 379 (if (eolp) |
371 (forward-line 1)))))) | 380 (condition-case err |
372 | 381 ;; Read the next form and make an autoload. |
373 (when done-any | 382 (let* ((form (prog1 (read (current-buffer)) |
374 (with-current-buffer outbuf | 383 (or (bolp) (forward-line 1)))) |
375 (save-excursion | 384 (autoload (make-autoload form load-name))) |
376 ;; Insert the section-header line which lists the file name | 385 (if autoload |
377 ;; and which functions are in it, etc. | 386 (push (nth 1 form) autoloads-done) |
378 (goto-char output-start) | 387 (setq autoload form)) |
379 (autoload-insert-section-header | 388 (let ((autoload-print-form-outbuf outbuf)) |
380 outbuf autoloads-done load-name file | 389 (autoload-print-form autoload))) |
381 (nth 5 (file-attributes file))) | 390 (error |
382 (insert ";;; Generated autoloads from " | 391 (message "Error in %s: %S" file err))) |
383 (autoload-trim-file-name file) "\n")) | 392 |
384 (insert generate-autoload-section-trailer))) | 393 ;; Copy the rest of the line to the output. |
385 (message "Generating autoloads for %s...done" file)) | 394 (princ (buffer-substring |
386 (or visited | 395 (progn |
387 ;; We created this buffer, so we should kill it. | 396 ;; Back up over whitespace, to preserve it. |
388 (kill-buffer (current-buffer)))) | 397 (skip-chars-backward " \f\t") |
389 (not done-any))) | 398 (if (= (char-after (1+ (point))) ? ) |
399 ;; Eat one space. | |
400 (forward-char 1)) | |
401 (point)) | |
402 (progn (forward-line 1) (point))) | |
403 outbuf))) | |
404 ((looking-at ";") | |
405 ;; Don't read the comment. | |
406 (forward-line 1)) | |
407 (t | |
408 (forward-sexp 1) | |
409 (forward-line 1)))))) | |
410 | |
411 (when output-start | |
412 (let ((secondary-autoloads-file-buf | |
413 (if (local-variable-p 'generated-autoload-file) | |
414 (current-buffer)))) | |
415 (with-current-buffer outbuf | |
416 (save-excursion | |
417 ;; Insert the section-header line which lists the file name | |
418 ;; and which functions are in it, etc. | |
419 (goto-char output-start) | |
420 (autoload-insert-section-header | |
421 outbuf autoloads-done load-name relfile | |
422 (if secondary-autoloads-file-buf | |
423 ;; MD5 checksums are much better because they do not | |
424 ;; change unless the file changes (so they'll be | |
425 ;; equal on two different systems and will change | |
426 ;; less often than time-stamps, thus leading to fewer | |
427 ;; unneeded changes causing spurious conflicts), but | |
428 ;; using time-stamps is a very useful optimization, | |
429 ;; so we use time-stamps for the main autoloads file | |
430 ;; (loaddefs.el) where we have special ways to | |
431 ;; circumvent the "random change problem", and MD5 | |
432 ;; checksum in secondary autoload files where we do | |
433 ;; not need the time-stamp optimization because it is | |
434 ;; already provided by the primary autoloads file. | |
435 (md5 secondary-autoloads-file-buf nil nil 'emacs-mule) | |
436 (nth 5 (file-attributes relfile)))) | |
437 (insert ";;; Generated autoloads from " relfile "\n")) | |
438 (insert generate-autoload-section-trailer)))) | |
439 (message "Generating autoloads for %s...done" file)) | |
440 (or visited | |
441 ;; We created this buffer, so we should kill it. | |
442 (kill-buffer (current-buffer)))) | |
443 ;; If the entries were added to some other buffer, then the file | |
444 ;; doesn't add entries to OUTFILE. | |
445 (or (not output-start) otherbuf)))) | |
390 | 446 |
447 (defun autoload-save-buffers () | |
448 (while autoload-modified-buffers | |
449 (with-current-buffer (pop autoload-modified-buffers) | |
450 (save-buffer)))) | |
451 | |
391 ;;;###autoload | 452 ;;;###autoload |
392 (defun update-file-autoloads (file &optional save-after) | 453 (defun update-file-autoloads (file &optional save-after) |
393 "Update the autoloads for FILE in `generated-autoload-file' | 454 "Update the autoloads for FILE in `generated-autoload-file' |
394 \(which FILE might bind in its local variables). | 455 \(which FILE might bind in its local variables). |
395 If SAVE-AFTER is non-nil (which is always, when called interactively), | 456 If SAVE-AFTER is non-nil (which is always, when called interactively), |
396 save the buffer too. | 457 save the buffer too. |
397 | 458 |
398 Return FILE if there was no autoload cookie in it, else nil." | 459 Return FILE if there was no autoload cookie in it, else nil." |
399 (interactive "fUpdate autoloads for file: \np") | 460 (interactive "fUpdate autoloads for file: \np") |
400 (let ((load-name (let ((name (file-name-nondirectory file))) | 461 (let* ((autoload-modified-buffers nil) |
401 (if (string-match "\\.elc?\\(\\.\\|$\\)" name) | 462 (no-autoloads (autoload-generate-file-autoloads file))) |
402 (substring name 0 (match-beginning 0)) | 463 (if autoload-modified-buffers |
403 name))) | 464 (if save-after (autoload-save-buffers)) |
404 (found nil) | 465 (if (interactive-p) |
405 (existing-buffer (get-file-buffer file)) | 466 (message "Autoload section for %s is up to date." file))) |
406 (no-autoloads nil)) | 467 (if no-autoloads file))) |
407 (save-excursion | 468 |
408 ;; We want to get a value for generated-autoload-file from | 469 (defun autoload-find-destination (file) |
409 ;; the local variables section if it's there. | 470 "Find the destination point of the current buffer's autoloads. |
410 (if existing-buffer | 471 FILE is the file name of the current buffer. |
411 (set-buffer existing-buffer)) | 472 Returns a buffer whose point is placed at the requested location. |
412 ;; We must read/write the file without any code conversion, | 473 Returns nil if the file's autoloads are uptodate, otherwise |
413 ;; but still decode EOLs. | 474 removes any prior now out-of-date autoload entries." |
414 (let ((coding-system-for-read 'raw-text)) | 475 (catch 'up-to-date |
415 (set-buffer (find-file-noselect | 476 (let* ((load-name (autoload-file-load-name file)) |
416 (autoload-ensure-default-file | 477 (buf (current-buffer)) |
417 (expand-file-name generated-autoload-file | 478 (existing-buffer (if buffer-file-name buf)) |
418 (expand-file-name "lisp" | 479 (found nil)) |
419 source-directory))))) | 480 (with-current-buffer |
420 ;; This is to make generated-autoload-file have Unix EOLs, so | 481 ;; We must read/write the file without any code conversion, |
421 ;; that it is portable to all platforms. | 482 ;; but still decode EOLs. |
422 (setq buffer-file-coding-system 'raw-text-unix)) | 483 (let ((coding-system-for-read 'raw-text)) |
423 (or (> (buffer-size) 0) | 484 (find-file-noselect |
424 (error "Autoloads file %s does not exist" buffer-file-name)) | 485 (autoload-ensure-default-file (autoload-generated-file)))) |
425 (or (file-writable-p buffer-file-name) | 486 ;; This is to make generated-autoload-file have Unix EOLs, so |
426 (error "Autoloads file %s is not writable" buffer-file-name)) | 487 ;; that it is portable to all platforms. |
427 (save-excursion | 488 (setq buffer-file-coding-system 'raw-text-unix) |
428 (save-restriction | 489 (or (> (buffer-size) 0) |
429 (widen) | 490 (error "Autoloads file %s does not exist" buffer-file-name)) |
430 (goto-char (point-min)) | 491 (or (file-writable-p buffer-file-name) |
431 ;; Look for the section for LOAD-NAME. | 492 (error "Autoloads file %s is not writable" buffer-file-name)) |
432 (while (and (not found) | 493 (widen) |
433 (search-forward generate-autoload-section-header nil t)) | 494 (goto-char (point-min)) |
434 (let ((form (autoload-read-section-header))) | 495 ;; Look for the section for LOAD-NAME. |
435 (cond ((string= (nth 2 form) load-name) | 496 (while (and (not found) |
436 ;; We found the section for this file. | 497 (search-forward generate-autoload-section-header nil t)) |
437 ;; Check if it is up to date. | 498 (let ((form (autoload-read-section-header))) |
438 (let ((begin (match-beginning 0)) | 499 (cond ((string= (nth 2 form) load-name) |
439 (last-time (nth 4 form)) | 500 ;; We found the section for this file. |
440 (file-time (nth 5 (file-attributes file)))) | 501 ;; Check if it is up to date. |
441 (if (and (or (null existing-buffer) | 502 (let ((begin (match-beginning 0)) |
442 (not (buffer-modified-p existing-buffer))) | 503 (last-time (nth 4 form)) |
443 (listp last-time) (= (length last-time) 2) | 504 (file-time (nth 5 (file-attributes file)))) |
444 (not (time-less-p last-time file-time))) | 505 (if (and (or (null existing-buffer) |
445 (progn | 506 (not (buffer-modified-p existing-buffer))) |
446 (if (interactive-p) | 507 (or |
447 (message "\ | 508 ;; last-time is the time-stamp (specifying |
448 Autoload section for %s is up to date." | 509 ;; the last time we looked at the file) and |
449 file)) | 510 ;; the file hasn't been changed since. |
450 (setq found 'up-to-date)) | 511 (and (listp last-time) (= (length last-time) 2) |
451 (search-forward generate-autoload-section-trailer) | 512 (not (time-less-p last-time file-time))) |
452 (delete-region begin (point)) | 513 ;; last-time is an MD5 checksum instead. |
453 (setq found t)))) | 514 (and (stringp last-time) |
454 ((string< load-name (nth 2 form)) | 515 (equal last-time |
455 ;; We've come to a section alphabetically later than | 516 (md5 buf nil nil 'emacs-mule))))) |
456 ;; LOAD-NAME. We assume the file is in order and so | 517 (throw 'up-to-date nil) |
457 ;; there must be no section for LOAD-NAME. We will | 518 (autoload-remove-section begin) |
458 ;; insert one before the section here. | 519 (setq found t)))) |
459 (goto-char (match-beginning 0)) | 520 ((string< load-name (nth 2 form)) |
460 (setq found 'new))))) | 521 ;; We've come to a section alphabetically later than |
461 (or found | 522 ;; LOAD-NAME. We assume the file is in order and so |
462 (progn | 523 ;; there must be no section for LOAD-NAME. We will |
463 (setq found 'new) | 524 ;; insert one before the section here. |
464 ;; No later sections in the file. Put before the last page. | 525 (goto-char (match-beginning 0)) |
465 (goto-char (point-max)) | 526 (setq found t))))) |
466 (search-backward "\f" nil t))) | 527 (or found |
467 (or (eq found 'up-to-date) | 528 (progn |
468 (setq no-autoloads (generate-file-autoloads file))))) | 529 ;; No later sections in the file. Put before the last page. |
469 (and save-after | 530 (goto-char (point-max)) |
470 (buffer-modified-p) | 531 (search-backward "\f" nil t))) |
471 (save-buffer)) | 532 (unless (memq (current-buffer) autoload-modified-buffers) |
472 | 533 (push (current-buffer) autoload-modified-buffers)) |
473 (if no-autoloads file)))) | 534 (current-buffer))))) |
474 | 535 |
475 (defun autoload-remove-section (begin) | 536 (defun autoload-remove-section (begin) |
476 (goto-char begin) | 537 (goto-char begin) |
477 (search-forward generate-autoload-section-trailer) | 538 (search-forward generate-autoload-section-trailer) |
478 (delete-region begin (point))) | 539 (delete-region begin (point))) |
497 (mapcar (lambda (dir) | 558 (mapcar (lambda (dir) |
498 (directory-files (expand-file-name dir) | 559 (directory-files (expand-file-name dir) |
499 t files-re)) | 560 t files-re)) |
500 dirs))) | 561 dirs))) |
501 (this-time (current-time)) | 562 (this-time (current-time)) |
502 (no-autoloads nil) ;files with no autoload cookies. | 563 ;; Files with no autoload cookies or whose autoloads go to other |
503 (autoloads-file | 564 ;; files because of file-local autoload-generated-file settings. |
504 (expand-file-name generated-autoload-file | 565 (no-autoloads nil) |
505 (expand-file-name "lisp" source-directory))) | 566 (autoload-modified-buffers nil)) |
506 (top-dir (file-name-directory autoloads-file))) | |
507 | 567 |
508 (with-current-buffer | 568 (with-current-buffer |
509 (find-file-noselect (autoload-ensure-default-file autoloads-file)) | 569 (find-file-noselect |
570 (autoload-ensure-default-file (autoload-generated-file))) | |
510 (save-excursion | 571 (save-excursion |
511 | 572 |
512 ;; Canonicalize file names and remove the autoload file itself. | 573 ;; Canonicalize file names and remove the autoload file itself. |
513 (setq files (delete (autoload-trim-file-name buffer-file-name) | 574 (setq files (delete (file-relative-name buffer-file-name) |
514 (mapcar 'autoload-trim-file-name files))) | 575 (mapcar 'file-relative-name files))) |
515 | 576 |
516 (goto-char (point-min)) | 577 (goto-char (point-min)) |
517 (while (search-forward generate-autoload-section-header nil t) | 578 (while (search-forward generate-autoload-section-header nil t) |
518 (let* ((form (autoload-read-section-header)) | 579 (let* ((form (autoload-read-section-header)) |
519 (file (nth 3 form))) | 580 (file (nth 3 form))) |
529 (not (time-less-p last-time file-time))) | 590 (not (time-less-p last-time file-time))) |
530 ;; file unchanged | 591 ;; file unchanged |
531 (push file no-autoloads) | 592 (push file no-autoloads) |
532 (setq files (delete file files))))))) | 593 (setq files (delete file files))))))) |
533 ((not (stringp file))) | 594 ((not (stringp file))) |
534 ((not (file-exists-p (expand-file-name file top-dir))) | 595 ((not (and (file-exists-p file) |
596 ;; Remove duplicates as well, just in case. | |
597 (member file files))) | |
535 ;; Remove the obsolete section. | 598 ;; Remove the obsolete section. |
536 (autoload-remove-section (match-beginning 0))) | 599 (autoload-remove-section (match-beginning 0))) |
537 ((equal (nth 4 form) (nth 5 (file-attributes file))) | 600 ((not (time-less-p (nth 4 form) |
601 (nth 5 (file-attributes file)))) | |
538 ;; File hasn't changed. | 602 ;; File hasn't changed. |
539 nil) | 603 nil) |
540 (t | 604 (t |
541 (update-file-autoloads file))) | 605 (autoload-remove-section (match-beginning 0)) |
606 (if (autoload-generate-file-autoloads | |
607 file (current-buffer) buffer-file-name) | |
608 (push file no-autoloads)))) | |
542 (setq files (delete file files))))) | 609 (setq files (delete file files))))) |
543 ;; Elements remaining in FILES have no existing autoload sections yet. | 610 ;; Elements remaining in FILES have no existing autoload sections yet. |
544 (setq no-autoloads | 611 (dolist (file files) |
545 (append no-autoloads | 612 (if (autoload-generate-file-autoloads file nil buffer-file-name) |
546 (delq nil (mapcar 'update-file-autoloads files)))) | 613 (push file no-autoloads))) |
614 | |
547 (when no-autoloads | 615 (when no-autoloads |
548 ;; Sort them for better readability. | 616 ;; Sort them for better readability. |
549 (setq no-autoloads (sort no-autoloads 'string<)) | 617 (setq no-autoloads (sort no-autoloads 'string<)) |
550 ;; Add the `no-autoloads' section. | 618 ;; Add the `no-autoloads' section. |
551 (goto-char (point-max)) | 619 (goto-char (point-max)) |
552 (search-backward "\f" nil t) | 620 (search-backward "\f" nil t) |
553 (autoload-insert-section-header | 621 (autoload-insert-section-header |
554 (current-buffer) nil nil no-autoloads this-time) | 622 (current-buffer) nil nil no-autoloads this-time) |
555 (insert generate-autoload-section-trailer)) | 623 (insert generate-autoload-section-trailer)) |
556 | 624 |
557 (save-buffer)))) | 625 (save-buffer) |
626 ;; In case autoload entries were added to other files because of | |
627 ;; file-local autoload-generated-file settings. | |
628 (autoload-save-buffers)))) | |
558 | 629 |
559 (define-obsolete-function-alias 'update-autoloads-from-directories | 630 (define-obsolete-function-alias 'update-autoloads-from-directories |
560 'update-directory-autoloads "22.1") | 631 'update-directory-autoloads "22.1") |
561 | 632 |
562 ;;;###autoload | 633 ;;;###autoload |