diff options
| author | Chong Yidong | 2012-06-27 13:47:14 +0800 |
|---|---|---|
| committer | Chong Yidong | 2012-06-27 13:47:14 +0800 |
| commit | c89926a5f14afd9c409f3ba20d9380e1c95d65cb (patch) | |
| tree | 4c8e5a1a4c333e19dcbdfb0de6b0663b3ae1b361 | |
| parent | a2eb421b874f9719a8d49b456518ceb20f2b616a (diff) | |
| download | emacs-c89926a5f14afd9c409f3ba20d9380e1c95d65cb.tar.gz emacs-c89926a5f14afd9c409f3ba20d9380e1c95d65cb.zip | |
Let C-h f do autoloading, and report if a function was previously autoloaded.
* lisp/help-fns.el (help-fns--autoloaded-p): New function.
(describe-function-1): Refer to a function as "autoloaded" if it
was autoloaded at any time in the past. Perform autoloading if
help-enable-auto-load is non-nil.
* lisp/help.el (help-enable-auto-load): New variable.
* src/doc.c (Fsubstitute_command_keys): Fix punctuation.
| -rw-r--r-- | etc/NEWS | 12 | ||||
| -rw-r--r-- | lisp/ChangeLog | 9 | ||||
| -rw-r--r-- | lisp/help-fns.el | 138 | ||||
| -rw-r--r-- | lisp/help.el | 10 | ||||
| -rw-r--r-- | src/ChangeLog | 4 | ||||
| -rw-r--r-- | src/doc.c | 4 |
6 files changed, 122 insertions, 55 deletions
| @@ -64,6 +64,18 @@ been adding them there, put them somewhere else, eg site-lisp. | |||
| 64 | 64 | ||
| 65 | * Changes in Emacs 24.2 | 65 | * Changes in Emacs 24.2 |
| 66 | 66 | ||
| 67 | ** Help changes | ||
| 68 | |||
| 69 | *** `C-h f' (describe-function) can now perform autoloading. | ||
| 70 | When this command is called for an autoloaded function whose docstring | ||
| 71 | contains a key substitution construct, that function's library is | ||
| 72 | automatically loaded, so that the documentation can be shown | ||
| 73 | correctly. To disable this, set `help-enable-auto-load' to nil. | ||
| 74 | |||
| 75 | *** `C-h f' now reports previously-autoloaded functions as "autoloaded", | ||
| 76 | even after their associated libraries have been loaded (and the | ||
| 77 | autoloads have been redefined as functions). | ||
| 78 | |||
| 67 | ** The function `current-time' now returns extended-format time stamps | 79 | ** The function `current-time' now returns extended-format time stamps |
| 68 | (HIGH LOW USEC PSEC) that use picosecond resolution; the PSEC | 80 | (HIGH LOW USEC PSEC) that use picosecond resolution; the PSEC |
| 69 | component is new. PSEC is typically a multiple of 1000 on current | 81 | component is new. PSEC is typically a multiple of 1000 on current |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 602c79854fa..c52891af605 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,12 @@ | |||
| 1 | 2012-06-27 Chong Yidong <cyd@gnu.org> | ||
| 2 | |||
| 3 | * help.el (help-enable-auto-load): New variable. | ||
| 4 | |||
| 5 | * help-fns.el (help-fns--autoloaded-p): New function. | ||
| 6 | (describe-function-1): Refer to a function as "autoloaded" if it | ||
| 7 | was autoloaded at any time in the past. Perform autoloading if | ||
| 8 | help-enable-auto-load is non-nil. | ||
| 9 | |||
| 1 | 2012-06-26 Eli Zaretskii <eliz@gnu.org> | 10 | 2012-06-26 Eli Zaretskii <eliz@gnu.org> |
| 2 | 11 | ||
| 3 | * makefile.w32-in (compile, compile-always): Depend on | 12 | * makefile.w32-in (compile, compile-always): Depend on |
diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 555bdbb69ce..52f1fe26056 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el | |||
| @@ -401,6 +401,21 @@ suitable file is found, return nil." | |||
| 401 | (help-xref-button 1 'help-function-cmacro function lib))))) | 401 | (help-xref-button 1 'help-function-cmacro function lib))))) |
| 402 | (princ ".\n\n")))) | 402 | (princ ".\n\n")))) |
| 403 | 403 | ||
| 404 | ;; We could use `symbol-file' but this is a wee bit more efficient. | ||
| 405 | (defun help-fns--autoloaded-p (function file) | ||
| 406 | "Return non-nil if FUNCTION has previously been autoloaded. | ||
| 407 | FILE is the file where FUNCTION was probably defined." | ||
| 408 | (let* ((file (file-name-sans-extension (file-truename file))) | ||
| 409 | (load-hist load-history) | ||
| 410 | (target (cons t function)) | ||
| 411 | found) | ||
| 412 | (while (and load-hist (not found)) | ||
| 413 | (and (caar load-hist) | ||
| 414 | (equal (file-name-sans-extension (caar load-hist)) file) | ||
| 415 | (setq found (member target (cdar load-hist)))) | ||
| 416 | (setq load-hist (cdr load-hist))) | ||
| 417 | found)) | ||
| 418 | |||
| 404 | ;;;###autoload | 419 | ;;;###autoload |
| 405 | (defun describe-function-1 (function) | 420 | (defun describe-function-1 (function) |
| 406 | (let* ((advised (and (symbolp function) (featurep 'advice) | 421 | (let* ((advised (and (symbolp function) (featurep 'advice) |
| @@ -416,59 +431,66 @@ suitable file is found, return nil." | |||
| 416 | (def (if (symbolp real-function) | 431 | (def (if (symbolp real-function) |
| 417 | (symbol-function real-function) | 432 | (symbol-function real-function) |
| 418 | function)) | 433 | function)) |
| 419 | file-name string | 434 | (aliased (symbolp def)) |
| 420 | (beg (if (commandp def) "an interactive " "a ")) | 435 | (real-def (if aliased |
| 436 | (let ((f def)) | ||
| 437 | (while (and (fboundp f) | ||
| 438 | (symbolp (symbol-function f))) | ||
| 439 | (setq f (symbol-function f))) | ||
| 440 | f) | ||
| 441 | def)) | ||
| 442 | (file-name (find-lisp-object-file-name function def)) | ||
| 421 | (pt1 (with-current-buffer (help-buffer) (point))) | 443 | (pt1 (with-current-buffer (help-buffer) (point))) |
| 422 | errtype) | 444 | (beg (if (and (or (byte-code-function-p def) |
| 423 | (setq string | 445 | (keymapp def) |
| 424 | (cond ((or (stringp def) (vectorp def)) | 446 | (memq (car-safe def) '(macro lambda closure))) |
| 425 | "a keyboard macro") | 447 | (help-fns--autoloaded-p function file-name)) |
| 426 | ((subrp def) | 448 | (if (commandp def) |
| 427 | (if (eq 'unevalled (cdr (subr-arity def))) | 449 | "an interactive autoloaded " |
| 428 | (concat beg "special form") | 450 | "an autoloaded ") |
| 429 | (concat beg "built-in function"))) | 451 | (if (commandp def) "an interactive " "a ")))) |
| 430 | ((byte-code-function-p def) | 452 | |
| 431 | (concat beg "compiled Lisp function")) | 453 | ;; Print what kind of function-like object FUNCTION is. |
| 432 | ((symbolp def) | 454 | (princ (cond ((or (stringp def) (vectorp def)) |
| 433 | (while (and (fboundp def) | 455 | "a keyboard macro") |
| 434 | (symbolp (symbol-function def))) | 456 | ((subrp def) |
| 435 | (setq def (symbol-function def))) | 457 | (if (eq 'unevalled (cdr (subr-arity def))) |
| 436 | ;; Handle (defalias 'foo 'bar), where bar is undefined. | 458 | (concat beg "special form") |
| 437 | (or (fboundp def) (setq errtype 'alias)) | 459 | (concat beg "built-in function"))) |
| 438 | (format "an alias for `%s'" def)) | 460 | ((byte-code-function-p def) |
| 439 | ((eq (car-safe def) 'lambda) | 461 | (concat beg "compiled Lisp function")) |
| 440 | (concat beg "Lisp function")) | 462 | (aliased |
| 441 | ((eq (car-safe def) 'macro) | 463 | (format "an alias for `%s'" real-def)) |
| 442 | "a Lisp macro") | 464 | ((eq (car-safe def) 'lambda) |
| 443 | ((eq (car-safe def) 'closure) | 465 | (concat beg "Lisp function")) |
| 444 | (concat beg "Lisp closure")) | 466 | ((eq (car-safe def) 'macro) |
| 445 | ((eq (car-safe def) 'autoload) | 467 | (concat beg "Lisp macro")) |
| 446 | (format "%s autoloaded %s" | 468 | ((eq (car-safe def) 'closure) |
| 447 | (if (commandp def) "an interactive" "an") | 469 | (concat beg "Lisp closure")) |
| 448 | (if (eq (nth 4 def) 'keymap) "keymap" | 470 | ((eq (car-safe def) 'autoload) |
| 449 | (if (nth 4 def) "Lisp macro" "Lisp function")))) | 471 | (format "%s autoloaded %s" |
| 450 | ((keymapp def) | 472 | (if (commandp def) "an interactive" "an") |
| 451 | (let ((is-full nil) | 473 | (if (eq (nth 4 def) 'keymap) "keymap" |
| 452 | (elts (cdr-safe def))) | 474 | (if (nth 4 def) "Lisp macro" "Lisp function")))) |
| 453 | (while elts | 475 | ((keymapp def) |
| 454 | (if (char-table-p (car-safe elts)) | 476 | (let ((is-full nil) |
| 455 | (setq is-full t | 477 | (elts (cdr-safe def))) |
| 456 | elts nil)) | 478 | (while elts |
| 457 | (setq elts (cdr-safe elts))) | 479 | (if (char-table-p (car-safe elts)) |
| 458 | (if is-full | 480 | (setq is-full t |
| 459 | "a full keymap" | 481 | elts nil)) |
| 460 | "a sparse keymap"))) | 482 | (setq elts (cdr-safe elts))) |
| 461 | (t ""))) | 483 | (concat beg (if is-full "keymap" "sparse keymap")))) |
| 462 | (princ string) | 484 | (t ""))) |
| 463 | (if (eq errtype 'alias) | 485 | |
| 486 | (if (and aliased (not (fboundp real-def))) | ||
| 464 | (princ ",\nwhich is not defined. Please make a bug report.") | 487 | (princ ",\nwhich is not defined. Please make a bug report.") |
| 465 | (with-current-buffer standard-output | 488 | (with-current-buffer standard-output |
| 466 | (save-excursion | 489 | (save-excursion |
| 467 | (save-match-data | 490 | (save-match-data |
| 468 | (when (re-search-backward "alias for `\\([^`']+\\)'" nil t) | 491 | (when (re-search-backward "alias for `\\([^`']+\\)'" nil t) |
| 469 | (help-xref-button 1 'help-function def))))) | 492 | (help-xref-button 1 'help-function real-def))))) |
| 470 | 493 | ||
| 471 | (setq file-name (find-lisp-object-file-name function def)) | ||
| 472 | (when file-name | 494 | (when file-name |
| 473 | (princ " in `") | 495 | (princ " in `") |
| 474 | ;; We used to add .el to the file name, | 496 | ;; We used to add .el to the file name, |
| @@ -531,11 +553,21 @@ suitable file is found, return nil." | |||
| 531 | (unless (looking-back "\n\n") | 553 | (unless (looking-back "\n\n") |
| 532 | (terpri))))) | 554 | (terpri))))) |
| 533 | (help-fns--compiler-macro function) | 555 | (help-fns--compiler-macro function) |
| 534 | (let* ((advertised (gethash def advertised-signature-table t)) | 556 | (let* ((advertised (gethash real-def advertised-signature-table t)) |
| 535 | (arglist (if (listp advertised) | 557 | (arglist (if (listp advertised) |
| 536 | advertised (help-function-arglist def))) | 558 | advertised (help-function-arglist real-def))) |
| 537 | (doc (condition-case err (documentation function) | 559 | (doc-raw (condition-case err |
| 538 | (error (format "No Doc! %S" err)))) | 560 | (documentation function t) |
| 561 | (error (format "No Doc! %S" err)))) | ||
| 562 | ;; If the function is autoloaded, and its docstring has | ||
| 563 | ;; key substitution constructs, load the library. | ||
| 564 | (doc (progn | ||
| 565 | (and (eq (car-safe real-def) 'autoload) | ||
| 566 | help-enable-auto-load | ||
| 567 | (string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]" | ||
| 568 | doc-raw) | ||
| 569 | (load (cadr real-def) t)) | ||
| 570 | (substitute-command-keys doc-raw))) | ||
| 539 | (usage (help-split-fundoc doc function))) | 571 | (usage (help-split-fundoc doc function))) |
| 540 | (with-current-buffer standard-output | 572 | (with-current-buffer standard-output |
| 541 | ;; If definition is a keymap, skip arglist note. | 573 | ;; If definition is a keymap, skip arglist note. |
| @@ -556,9 +588,9 @@ suitable file is found, return nil." | |||
| 556 | function))))) | 588 | function))))) |
| 557 | usage) | 589 | usage) |
| 558 | (car usage)) | 590 | (car usage)) |
| 559 | ((or (stringp def) | 591 | ((or (stringp real-def) |
| 560 | (vectorp def)) | 592 | (vectorp real-def)) |
| 561 | (format "\nMacro: %s" (format-kbd-macro def))) | 593 | (format "\nMacro: %s" (format-kbd-macro real-def))) |
| 562 | (t "[Missing arglist. Please make a bug report.]"))) | 594 | (t "[Missing arglist. Please make a bug report.]"))) |
| 563 | (high (help-highlight-arguments use doc))) | 595 | (high (help-highlight-arguments use doc))) |
| 564 | (let ((fill-begin (point))) | 596 | (let ((fill-begin (point))) |
diff --git a/lisp/help.el b/lisp/help.el index 2dbb31de97b..c02b058fef9 100644 --- a/lisp/help.el +++ b/lisp/help.el | |||
| @@ -1030,6 +1030,16 @@ by `with-help-window'" | |||
| 1030 | :group 'help | 1030 | :group 'help |
| 1031 | :version "23.1") | 1031 | :version "23.1") |
| 1032 | 1032 | ||
| 1033 | (defcustom help-enable-auto-load t | ||
| 1034 | "Whether Help commands can perform autoloading. | ||
| 1035 | If non-nil, whenever \\[describe-function] is called for an | ||
| 1036 | autoloaded function whose docstring contains any key substitution | ||
| 1037 | construct (see `substitute-command-keys'), the library is loaded, | ||
| 1038 | so that the documentation can show the right key bindings." | ||
| 1039 | :type 'boolean | ||
| 1040 | :group 'help | ||
| 1041 | :version "24.2") | ||
| 1042 | |||
| 1033 | (defun help-window-display-message (quit-part window &optional scroll) | 1043 | (defun help-window-display-message (quit-part window &optional scroll) |
| 1034 | "Display message telling how to quit and scroll help window. | 1044 | "Display message telling how to quit and scroll help window. |
| 1035 | QUIT-PART is a string telling how to quit the help window WINDOW. | 1045 | QUIT-PART is a string telling how to quit the help window WINDOW. |
diff --git a/src/ChangeLog b/src/ChangeLog index bef3bbd4c83..4614ba09b3d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2012-06-27 Chong Yidong <cyd@gnu.org> | ||
| 2 | |||
| 3 | * doc.c (Fsubstitute_command_keys): Fix punctuation. | ||
| 4 | |||
| 1 | 2012-06-26 John Wiegley <johnw@newartisans.com> | 5 | 2012-06-26 John Wiegley <johnw@newartisans.com> |
| 2 | 6 | ||
| 3 | * unexmacosx.c (copy_data_segment): Added two section names used | 7 | * unexmacosx.c (copy_data_segment): Added two section names used |
| @@ -897,11 +897,11 @@ Otherwise, return a new string, without any text properties. */) | |||
| 897 | if (NILP (tem)) | 897 | if (NILP (tem)) |
| 898 | { | 898 | { |
| 899 | name = Fsymbol_name (name); | 899 | name = Fsymbol_name (name); |
| 900 | insert_string ("\nUses keymap \""); | 900 | insert_string ("\nUses keymap `"); |
| 901 | insert_from_string (name, 0, 0, | 901 | insert_from_string (name, 0, 0, |
| 902 | SCHARS (name), | 902 | SCHARS (name), |
| 903 | SBYTES (name), 1); | 903 | SBYTES (name), 1); |
| 904 | insert_string ("\", which is not currently defined.\n"); | 904 | insert_string ("', which is not currently defined.\n"); |
| 905 | if (start[-1] == '<') keymap = Qnil; | 905 | if (start[-1] == '<') keymap = Qnil; |
| 906 | } | 906 | } |
| 907 | else if (start[-1] == '<') | 907 | else if (start[-1] == '<') |