aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChong Yidong2012-06-27 13:47:14 +0800
committerChong Yidong2012-06-27 13:47:14 +0800
commitc89926a5f14afd9c409f3ba20d9380e1c95d65cb (patch)
tree4c8e5a1a4c333e19dcbdfb0de6b0663b3ae1b361
parenta2eb421b874f9719a8d49b456518ceb20f2b616a (diff)
downloademacs-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/NEWS12
-rw-r--r--lisp/ChangeLog9
-rw-r--r--lisp/help-fns.el138
-rw-r--r--lisp/help.el10
-rw-r--r--src/ChangeLog4
-rw-r--r--src/doc.c4
6 files changed, 122 insertions, 55 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 585a91decab..e804805c8d0 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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.
70When this command is called for an autoloaded function whose docstring
71contains a key substitution construct, that function's library is
72automatically loaded, so that the documentation can be shown
73correctly. To disable this, set `help-enable-auto-load' to nil.
74
75*** `C-h f' now reports previously-autoloaded functions as "autoloaded",
76even after their associated libraries have been loaded (and the
77autoloads 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
69component is new. PSEC is typically a multiple of 1000 on current 81component 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 @@
12012-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
12012-06-26 Eli Zaretskii <eliz@gnu.org> 102012-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.
407FILE 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.
1035If non-nil, whenever \\[describe-function] is called for an
1036autoloaded function whose docstring contains any key substitution
1037construct (see `substitute-command-keys'), the library is loaded,
1038so 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.
1035QUIT-PART is a string telling how to quit the help window WINDOW. 1045QUIT-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 @@
12012-06-27 Chong Yidong <cyd@gnu.org>
2
3 * doc.c (Fsubstitute_command_keys): Fix punctuation.
4
12012-06-26 John Wiegley <johnw@newartisans.com> 52012-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
diff --git a/src/doc.c b/src/doc.c
index 223741c3bf5..cbfeb06756e 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -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] == '<')