Mercurial > emacs
comparison lisp/emacs-lisp/autoload.el @ 81622:9d32dd7131c3
(autoload-find-destination): Return nil
rather than throwing `up-to-date'.
(autoload-generate-file-autoloads): Adjust correspondingly.
(update-file-autoloads): Be careful to let-bind
autoload-modified-buffers and adjust to new calling conventions.
(autoload-modified-buffers): Make it a dynamically scoped var.
(update-directory-autoloads): Use file-relative-name instead of
autoload-trim-file-name.
(autoload-insert-section-header): Don't use autoload-trim-file-name
since the file is already relative now.
(autoload-trim-file-name): Remove.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Tue, 26 Jun 2007 19:07:14 +0000 |
parents | 56b815dd1abb |
children | 835baa7a130c |
comparison
equal
deleted
inserted
replaced
81621:6683a94d3fcb | 81622:9d32dd7131c3 |
---|---|
65 (defconst generate-autoload-section-trailer "\n;;;***\n" | 65 (defconst generate-autoload-section-trailer "\n;;;***\n" |
66 "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.") |
67 | 67 |
68 (defconst generate-autoload-section-continuation ";;;;;; " | 68 (defconst generate-autoload-section-continuation ";;;;;; " |
69 "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. | |
70 | 72 |
71 (defun make-autoload (form file) | 73 (defun make-autoload (form file) |
72 "Turn FORM into an autoload or defvar for source file FILE. | 74 "Turn FORM into an autoload or defvar for source file FILE. |
73 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 |
74 or macro definition or a defcustom)." | 76 or macro definition or a defcustom)." |
154 | 156 |
155 (defun autoload-generated-file () | 157 (defun autoload-generated-file () |
156 (expand-file-name generated-autoload-file | 158 (expand-file-name generated-autoload-file |
157 (expand-file-name "lisp" | 159 (expand-file-name "lisp" |
158 source-directory))) | 160 source-directory))) |
159 | |
160 (defun autoload-trim-file-name (file) | |
161 ;; Returns a relative file path for FILE | |
162 ;; starting from the directory that loaddefs.el is in. | |
163 ;; That is normally a directory in load-path, | |
164 ;; which means Emacs will be able to find FILE when it looks. | |
165 ;; Any extra directory names here would prevent finding the file. | |
166 (setq file (expand-file-name file)) | |
167 (file-relative-name file | |
168 (file-name-directory generated-autoload-file))) | |
169 | 161 |
170 (defun autoload-read-section-header () | 162 (defun autoload-read-section-header () |
171 "Read a section header form. | 163 "Read a section header form. |
172 Since continuation lines have been marked as comments, | 164 Since continuation lines have been marked as comments, |
173 we must copy the text of the form and remove those comment | 165 we must copy the text of the form and remove those comment |
258 | 250 |
259 (defun autoload-insert-section-header (outbuf autoloads load-name file time) | 251 (defun autoload-insert-section-header (outbuf autoloads load-name file time) |
260 "Insert the section-header line, | 252 "Insert the section-header line, |
261 which lists the file name and which functions are in it, etc." | 253 which lists the file name and which functions are in it, etc." |
262 (insert generate-autoload-section-header) | 254 (insert generate-autoload-section-header) |
263 (prin1 (list 'autoloads autoloads load-name | 255 (prin1 (list 'autoloads autoloads load-name file time) |
264 (if (stringp file) (autoload-trim-file-name file) file) | |
265 time) | |
266 outbuf) | 256 outbuf) |
267 (terpri outbuf) | 257 (terpri outbuf) |
268 ;; Break that line at spaces, to avoid very long lines. | 258 ;; Break that line at spaces, to avoid very long lines. |
269 ;; Make each sub-line into a comment. | 259 ;; Make each sub-line into a comment. |
270 (with-current-buffer outbuf | 260 (with-current-buffer outbuf |
316 Autoloads are generated for defuns and defmacros in FILE | 306 Autoloads are generated for defuns and defmacros in FILE |
317 marked by `generate-autoload-cookie' (which see). | 307 marked by `generate-autoload-cookie' (which see). |
318 If FILE is being visited in a buffer, the contents of the buffer are used. | 308 If FILE is being visited in a buffer, the contents of the buffer are used. |
319 OUTBUF is the buffer in which the autoload statements will be inserted. | 309 OUTBUF is the buffer in which the autoload statements will be inserted. |
320 If OUTBUF is nil, it will be determined by `autoload-generated-file'. | 310 If OUTBUF is nil, it will be determined by `autoload-generated-file'. |
321 Return non-nil in the case where no autoloads were added to OUTBUF. | 311 |
322 | 312 Return non-nil iff FILE adds no autoloads to OUTBUF." |
323 Can throw `up-to-date' to mean that the entries were found already and are | 313 (catch 'done |
324 up-to-date. Of course, this can only be the case if OUTBUF is not used." | 314 (let ((autoloads-done '()) |
325 (let ((autoloads-done '()) | 315 (load-name (autoload-file-load-name file)) |
326 (load-name (autoload-file-load-name file)) | 316 (print-length nil) |
327 (print-length nil) | 317 (print-readably t) ; This does something in Lucid Emacs. |
328 (print-readably t) ; This does something in Lucid Emacs. | 318 (float-output-format nil) |
329 (float-output-format nil) | 319 (visited (get-file-buffer file)) |
330 (visited (get-file-buffer file)) | 320 (absfile (expand-file-name file)) |
331 (absfile (expand-file-name file)) | 321 relfile |
332 relfile | 322 ;; nil until we found a cookie. |
333 ;; nil until we found a cookie. | 323 output-start) |
334 output-start) | 324 |
335 | 325 (with-current-buffer (or visited |
336 (with-current-buffer (or visited | 326 ;; It is faster to avoid visiting the file. |
337 ;; It is faster to avoid visiting the file. | 327 (autoload-find-file file)) |
338 (autoload-find-file file)) | 328 ;; Obey the no-update-autoloads file local variable. |
339 ;; Obey the no-update-autoloads file local variable. | 329 (unless no-update-autoloads |
340 (unless no-update-autoloads | 330 (message "Generating autoloads for %s..." file) |
341 (message "Generating autoloads for %s..." file) | 331 (save-excursion |
342 (save-excursion | 332 (save-restriction |
343 (save-restriction | 333 (widen) |
344 (widen) | 334 (goto-char (point-min)) |
345 (goto-char (point-min)) | 335 (while (not (eobp)) |
346 (while (not (eobp)) | 336 (skip-chars-forward " \t\n\f") |
347 (skip-chars-forward " \t\n\f") | 337 (cond |
348 (cond | 338 ((looking-at (regexp-quote generate-autoload-cookie)) |
349 ((looking-at (regexp-quote generate-autoload-cookie)) | 339 ;; If not done yet, figure out where to insert this text. |
350 ;; If not done yet, figure out where to insert this text. | 340 (unless output-start |
351 (unless output-start | 341 (unless outbuf |
352 (unless outbuf | 342 (setq outbuf (autoload-find-destination absfile)) |
353 (setq outbuf (autoload-find-destination absfile))) | 343 (unless outbuf |
354 (with-current-buffer outbuf | 344 ;; The file has autoload cookies, but they're |
355 (setq relfile (file-relative-name absfile)) | 345 ;; already up-to-date. |
356 (setq output-start (point))) | 346 (throw 'done t))) |
357 ;; (message "file=%S, relfile=%S, dest=%S" | 347 (with-current-buffer outbuf |
358 ;; file relfile (autoload-generated-file)) | 348 (setq relfile (file-relative-name absfile)) |
359 ) | 349 (setq output-start (point))) |
360 (search-forward generate-autoload-cookie) | 350 ;; (message "file=%S, relfile=%S, dest=%S" |
361 (skip-chars-forward " \t") | 351 ;; file relfile (autoload-generated-file)) |
362 (if (eolp) | 352 ) |
363 (condition-case err | 353 (search-forward generate-autoload-cookie) |
364 ;; Read the next form and make an autoload. | 354 (skip-chars-forward " \t") |
365 (let* ((form (prog1 (read (current-buffer)) | 355 (if (eolp) |
366 (or (bolp) (forward-line 1)))) | 356 (condition-case err |
367 (autoload (make-autoload form load-name))) | 357 ;; Read the next form and make an autoload. |
368 (if autoload | 358 (let* ((form (prog1 (read (current-buffer)) |
369 (push (nth 1 form) autoloads-done) | 359 (or (bolp) (forward-line 1)))) |
370 (setq autoload form)) | 360 (autoload (make-autoload form load-name))) |
371 (let ((autoload-print-form-outbuf outbuf)) | 361 (if autoload |
372 (autoload-print-form autoload))) | 362 (push (nth 1 form) autoloads-done) |
373 (error | 363 (setq autoload form)) |
374 (message "Error in %s: %S" file err))) | 364 (let ((autoload-print-form-outbuf outbuf)) |
375 | 365 (autoload-print-form autoload))) |
376 ;; Copy the rest of the line to the output. | 366 (error |
377 (princ (buffer-substring | 367 (message "Error in %s: %S" file err))) |
378 (progn | 368 |
379 ;; Back up over whitespace, to preserve it. | 369 ;; Copy the rest of the line to the output. |
380 (skip-chars-backward " \f\t") | 370 (princ (buffer-substring |
381 (if (= (char-after (1+ (point))) ? ) | 371 (progn |
382 ;; Eat one space. | 372 ;; Back up over whitespace, to preserve it. |
383 (forward-char 1)) | 373 (skip-chars-backward " \f\t") |
384 (point)) | 374 (if (= (char-after (1+ (point))) ? ) |
385 (progn (forward-line 1) (point))) | 375 ;; Eat one space. |
386 outbuf))) | 376 (forward-char 1)) |
387 ((looking-at ";") | 377 (point)) |
388 ;; Don't read the comment. | 378 (progn (forward-line 1) (point))) |
389 (forward-line 1)) | 379 outbuf))) |
390 (t | 380 ((looking-at ";") |
391 (forward-sexp 1) | 381 ;; Don't read the comment. |
392 (forward-line 1)))))) | 382 (forward-line 1)) |
393 | 383 (t |
394 (when output-start | 384 (forward-sexp 1) |
395 (with-current-buffer outbuf | 385 (forward-line 1)))))) |
396 (save-excursion | 386 |
397 ;; Insert the section-header line which lists the file name | 387 (when output-start |
398 ;; and which functions are in it, etc. | 388 (with-current-buffer outbuf |
399 (goto-char output-start) | 389 (save-excursion |
400 (autoload-insert-section-header | 390 ;; Insert the section-header line which lists the file name |
401 outbuf autoloads-done load-name relfile | 391 ;; and which functions are in it, etc. |
402 (nth 5 (file-attributes relfile))) | 392 (goto-char output-start) |
403 (insert ";;; Generated autoloads from " relfile "\n")) | 393 (autoload-insert-section-header |
404 (insert generate-autoload-section-trailer))) | 394 outbuf autoloads-done load-name relfile |
405 (message "Generating autoloads for %s...done" file)) | 395 (nth 5 (file-attributes relfile))) |
406 (or visited | 396 (insert ";;; Generated autoloads from " relfile "\n")) |
407 ;; We created this buffer, so we should kill it. | 397 (insert generate-autoload-section-trailer))) |
408 (kill-buffer (current-buffer)))) | 398 (message "Generating autoloads for %s...done" file)) |
409 (not output-start))) | 399 (or visited |
400 ;; We created this buffer, so we should kill it. | |
401 (kill-buffer (current-buffer)))) | |
402 (not output-start)))) | |
410 | 403 |
411 (defvar autoload-modified-buffers nil) | |
412 | |
413 (defun autoload-save-buffers () | 404 (defun autoload-save-buffers () |
414 (while autoload-modified-buffers | 405 (while autoload-modified-buffers |
415 (with-current-buffer (pop autoload-modified-buffers) | 406 (with-current-buffer (pop autoload-modified-buffers) |
416 (save-buffer)))) | 407 (save-buffer)))) |
417 | 408 |
422 If SAVE-AFTER is non-nil (which is always, when called interactively), | 413 If SAVE-AFTER is non-nil (which is always, when called interactively), |
423 save the buffer too. | 414 save the buffer too. |
424 | 415 |
425 Return FILE if there was no autoload cookie in it, else nil." | 416 Return FILE if there was no autoload cookie in it, else nil." |
426 (interactive "fUpdate autoloads for file: \np") | 417 (interactive "fUpdate autoloads for file: \np") |
427 (let ((no-autoloads nil)) | 418 (let* ((autoload-modified-buffers nil) |
428 (if (catch 'up-to-date | 419 (no-autoloads (autoload-generate-file-autoloads file))) |
429 (progn | 420 (if autoload-modified-buffers |
430 (setq no-autoloads (autoload-generate-file-autoloads file)) | |
431 t)) | |
432 (if save-after (autoload-save-buffers)) | 421 (if save-after (autoload-save-buffers)) |
433 (if (interactive-p) | 422 (if (interactive-p) |
434 (message "Autoload section for %s is up to date." file))) | 423 (message "Autoload section for %s is up to date." file))) |
435 ;; If we caught `up-to-date', it means there are autoload entries, since | |
436 ;; otherwise we wouldn't have detected their up-to-dateness. | |
437 (if no-autoloads file))) | 424 (if no-autoloads file))) |
438 | 425 |
439 (defun autoload-find-destination (file) | 426 (defun autoload-find-destination (file) |
440 "Find the destination point of the current buffer's autoloads. | 427 "Find the destination point of the current buffer's autoloads. |
441 FILE is the file name of the current buffer. | 428 FILE is the file name of the current buffer. |
442 Returns a buffer whose point is placed at the requested location. | 429 Returns a buffer whose point is placed at the requested location. |
443 Throws `up-to-date' if the file's autoloads are uptodate, otherwise | 430 Returns nil if the file's autoloads are uptodate, otherwise |
444 removes any prior now out-of-date autoload entries. | 431 removes any prior now out-of-date autoload entries. |
445 The current buffer only matters if it is visiting a file or if it has a buffer-local | 432 The current buffer only matters if it is visiting a file or if it has a buffer-local |
446 value for some variables such as `generated-autoload-file', so it's OK | 433 value for some variables such as `generated-autoload-file', so it's OK |
447 to call it from a dummy buffer if FILE is not currently visited." | 434 to call it from a dummy buffer if FILE is not currently visited." |
448 ;; (message "autoload-find-destination %S" file) | 435 (catch 'up-to-date |
449 (let ((load-name (autoload-file-load-name file)) | 436 (let ((load-name (autoload-file-load-name file)) |
450 (existing-buffer (if buffer-file-name (current-buffer))) | 437 (existing-buffer (if buffer-file-name (current-buffer))) |
451 (found nil)) | 438 (found nil)) |
452 (with-current-buffer | 439 (with-current-buffer |
453 ;; We must read/write the file without any code conversion, | 440 ;; We must read/write the file without any code conversion, |
454 ;; but still decode EOLs. | 441 ;; but still decode EOLs. |
455 (let ((coding-system-for-read 'raw-text)) | 442 (let ((coding-system-for-read 'raw-text)) |
456 (find-file-noselect | 443 (find-file-noselect |
457 (autoload-ensure-default-file (autoload-generated-file)))) | 444 (autoload-ensure-default-file (autoload-generated-file)))) |
458 ;; This is to make generated-autoload-file have Unix EOLs, so | 445 ;; This is to make generated-autoload-file have Unix EOLs, so |
459 ;; that it is portable to all platforms. | 446 ;; that it is portable to all platforms. |
460 (setq buffer-file-coding-system 'raw-text-unix) | 447 (setq buffer-file-coding-system 'raw-text-unix) |
461 (or (> (buffer-size) 0) | 448 (or (> (buffer-size) 0) |
462 (error "Autoloads file %s does not exist" buffer-file-name)) | 449 (error "Autoloads file %s does not exist" buffer-file-name)) |
463 (or (file-writable-p buffer-file-name) | 450 (or (file-writable-p buffer-file-name) |
464 (error "Autoloads file %s is not writable" buffer-file-name)) | 451 (error "Autoloads file %s is not writable" buffer-file-name)) |
465 (widen) | 452 (widen) |
466 (goto-char (point-min)) | 453 (goto-char (point-min)) |
467 ;; Look for the section for LOAD-NAME. | 454 ;; Look for the section for LOAD-NAME. |
468 (while (and (not found) | 455 (while (and (not found) |
469 (search-forward generate-autoload-section-header nil t)) | 456 (search-forward generate-autoload-section-header nil t)) |
470 (let ((form (autoload-read-section-header))) | 457 (let ((form (autoload-read-section-header))) |
471 (cond ((string= (nth 2 form) load-name) | 458 (cond ((string= (nth 2 form) load-name) |
472 ;; We found the section for this file. | 459 ;; We found the section for this file. |
473 ;; Check if it is up to date. | 460 ;; Check if it is up to date. |
474 (let ((begin (match-beginning 0)) | 461 (let ((begin (match-beginning 0)) |
475 (last-time (nth 4 form)) | 462 (last-time (nth 4 form)) |
476 (file-time (nth 5 (file-attributes file)))) | 463 (file-time (nth 5 (file-attributes file)))) |
477 (if (and (or (null existing-buffer) | 464 (if (and (or (null existing-buffer) |
478 (not (buffer-modified-p existing-buffer))) | 465 (not (buffer-modified-p existing-buffer))) |
479 (listp last-time) (= (length last-time) 2) | 466 (listp last-time) (= (length last-time) 2) |
480 (not (time-less-p last-time file-time))) | 467 (not (time-less-p last-time file-time))) |
481 (throw 'up-to-date nil) | 468 (throw 'up-to-date nil) |
482 (autoload-remove-section begin) | 469 (autoload-remove-section begin) |
483 (setq found t)))) | 470 (setq found t)))) |
484 ((string< load-name (nth 2 form)) | 471 ((string< load-name (nth 2 form)) |
485 ;; We've come to a section alphabetically later than | 472 ;; We've come to a section alphabetically later than |
486 ;; LOAD-NAME. We assume the file is in order and so | 473 ;; LOAD-NAME. We assume the file is in order and so |
487 ;; there must be no section for LOAD-NAME. We will | 474 ;; there must be no section for LOAD-NAME. We will |
488 ;; insert one before the section here. | 475 ;; insert one before the section here. |
489 (goto-char (match-beginning 0)) | 476 (goto-char (match-beginning 0)) |
490 (setq found t))))) | 477 (setq found t))))) |
491 (or found | 478 (or found |
492 (progn | 479 (progn |
493 ;; No later sections in the file. Put before the last page. | 480 ;; No later sections in the file. Put before the last page. |
494 (goto-char (point-max)) | 481 (goto-char (point-max)) |
495 (search-backward "\f" nil t))) | 482 (search-backward "\f" nil t))) |
496 (unless (memq (current-buffer) autoload-modified-buffers) | 483 (unless (memq (current-buffer) autoload-modified-buffers) |
497 (push (current-buffer) autoload-modified-buffers)) | 484 (push (current-buffer) autoload-modified-buffers)) |
498 (current-buffer)))) | 485 (current-buffer))))) |
499 | 486 |
500 (defun autoload-remove-section (begin) | 487 (defun autoload-remove-section (begin) |
501 (goto-char begin) | 488 (goto-char begin) |
502 (search-forward generate-autoload-section-trailer) | 489 (search-forward generate-autoload-section-trailer) |
503 (delete-region begin (point))) | 490 (delete-region begin (point))) |
531 (with-current-buffer | 518 (with-current-buffer |
532 (find-file-noselect (autoload-ensure-default-file autoloads-file)) | 519 (find-file-noselect (autoload-ensure-default-file autoloads-file)) |
533 (save-excursion | 520 (save-excursion |
534 | 521 |
535 ;; Canonicalize file names and remove the autoload file itself. | 522 ;; Canonicalize file names and remove the autoload file itself. |
536 (setq files (delete (autoload-trim-file-name buffer-file-name) | 523 (setq files (delete (file-relative-name buffer-file-name) |
537 (mapcar 'autoload-trim-file-name files))) | 524 (mapcar 'file-relative-name files))) |
538 | 525 |
539 (goto-char (point-min)) | 526 (goto-char (point-min)) |
540 (while (search-forward generate-autoload-section-header nil t) | 527 (while (search-forward generate-autoload-section-header nil t) |
541 (let* ((form (autoload-read-section-header)) | 528 (let* ((form (autoload-read-section-header)) |
542 (file (nth 3 form))) | 529 (file (nth 3 form))) |