summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChong Yidong <cyd@gnu.org>2012-06-27 13:47:14 +0800
committerChong Yidong <cyd@gnu.org>2012-06-27 13:47:14 +0800
commitc89926a5f14afd9c409f3ba20d9380e1c95d65cb (patch)
tree4c8e5a1a4c333e19dcbdfb0de6b0663b3ae1b361
parenta2eb421b874f9719a8d49b456518ceb20f2b616a (diff)
downloademacs-c89926a5f14afd9c409f3ba20d9380e1c95d65cb.tar.gz
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.
* Changes in Emacs 24.2
+** Help changes
+
+*** `C-h f' (describe-function) can now perform autoloading.
+When this command is called for an autoloaded function whose docstring
+contains a key substitution construct, that function's library is
+automatically loaded, so that the documentation can be shown
+correctly. To disable this, set `help-enable-auto-load' to nil.
+
+*** `C-h f' now reports previously-autoloaded functions as "autoloaded",
+even after their associated libraries have been loaded (and the
+autoloads have been redefined as functions).
+
** The function `current-time' now returns extended-format time stamps
(HIGH LOW USEC PSEC) that use picosecond resolution; the PSEC
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 @@
+2012-06-27 Chong Yidong <cyd@gnu.org>
+
+ * help.el (help-enable-auto-load): New variable.
+
+ * 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.
+
2012-06-26 Eli Zaretskii <eliz@gnu.org>
* 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."
(help-xref-button 1 'help-function-cmacro function lib)))))
(princ ".\n\n"))))
+;; We could use `symbol-file' but this is a wee bit more efficient.
+(defun help-fns--autoloaded-p (function file)
+ "Return non-nil if FUNCTION has previously been autoloaded.
+FILE is the file where FUNCTION was probably defined."
+ (let* ((file (file-name-sans-extension (file-truename file)))
+ (load-hist load-history)
+ (target (cons t function))
+ found)
+ (while (and load-hist (not found))
+ (and (caar load-hist)
+ (equal (file-name-sans-extension (caar load-hist)) file)
+ (setq found (member target (cdar load-hist))))
+ (setq load-hist (cdr load-hist)))
+ found))
+
;;;###autoload
(defun describe-function-1 (function)
(let* ((advised (and (symbolp function) (featurep 'advice)
@@ -416,59 +431,66 @@ suitable file is found, return nil."
(def (if (symbolp real-function)
(symbol-function real-function)
function))
- file-name string
- (beg (if (commandp def) "an interactive " "a "))
+ (aliased (symbolp def))
+ (real-def (if aliased
+ (let ((f def))
+ (while (and (fboundp f)
+ (symbolp (symbol-function f)))
+ (setq f (symbol-function f)))
+ f)
+ def))
+ (file-name (find-lisp-object-file-name function def))
(pt1 (with-current-buffer (help-buffer) (point)))
- errtype)
- (setq string
- (cond ((or (stringp def) (vectorp def))
- "a keyboard macro")
- ((subrp def)
- (if (eq 'unevalled (cdr (subr-arity def)))
- (concat beg "special form")
- (concat beg "built-in function")))
- ((byte-code-function-p def)
- (concat beg "compiled Lisp function"))
- ((symbolp def)
- (while (and (fboundp def)
- (symbolp (symbol-function def)))
- (setq def (symbol-function def)))
- ;; Handle (defalias 'foo 'bar), where bar is undefined.
- (or (fboundp def) (setq errtype 'alias))
- (format "an alias for `%s'" def))
- ((eq (car-safe def) 'lambda)
- (concat beg "Lisp function"))
- ((eq (car-safe def) 'macro)
- "a Lisp macro")
- ((eq (car-safe def) 'closure)
- (concat beg "Lisp closure"))
- ((eq (car-safe def) 'autoload)
- (format "%s autoloaded %s"
- (if (commandp def) "an interactive" "an")
- (if (eq (nth 4 def) 'keymap) "keymap"
- (if (nth 4 def) "Lisp macro" "Lisp function"))))
- ((keymapp def)
- (let ((is-full nil)
- (elts (cdr-safe def)))
- (while elts
- (if (char-table-p (car-safe elts))
- (setq is-full t
- elts nil))
- (setq elts (cdr-safe elts)))
- (if is-full
- "a full keymap"
- "a sparse keymap")))
- (t "")))
- (princ string)
- (if (eq errtype 'alias)
+ (beg (if (and (or (byte-code-function-p def)
+ (keymapp def)
+ (memq (car-safe def) '(macro lambda closure)))
+ (help-fns--autoloaded-p function file-name))
+ (if (commandp def)
+ "an interactive autoloaded "
+ "an autoloaded ")
+ (if (commandp def) "an interactive " "a "))))
+
+ ;; Print what kind of function-like object FUNCTION is.
+ (princ (cond ((or (stringp def) (vectorp def))
+ "a keyboard macro")
+ ((subrp def)
+ (if (eq 'unevalled (cdr (subr-arity def)))
+ (concat beg "special form")
+ (concat beg "built-in function")))
+ ((byte-code-function-p def)
+ (concat beg "compiled Lisp function"))
+ (aliased
+ (format "an alias for `%s'" real-def))
+ ((eq (car-safe def) 'lambda)
+ (concat beg "Lisp function"))
+ ((eq (car-safe def) 'macro)
+ (concat beg "Lisp macro"))
+ ((eq (car-safe def) 'closure)
+ (concat beg "Lisp closure"))
+ ((eq (car-safe def) 'autoload)
+ (format "%s autoloaded %s"
+ (if (commandp def) "an interactive" "an")
+ (if (eq (nth 4 def) 'keymap) "keymap"
+ (if (nth 4 def) "Lisp macro" "Lisp function"))))
+ ((keymapp def)
+ (let ((is-full nil)
+ (elts (cdr-safe def)))
+ (while elts
+ (if (char-table-p (car-safe elts))
+ (setq is-full t
+ elts nil))
+ (setq elts (cdr-safe elts)))
+ (concat beg (if is-full "keymap" "sparse keymap"))))
+ (t "")))
+
+ (if (and aliased (not (fboundp real-def)))
(princ ",\nwhich is not defined. Please make a bug report.")
(with-current-buffer standard-output
(save-excursion
(save-match-data
(when (re-search-backward "alias for `\\([^`']+\\)'" nil t)
- (help-xref-button 1 'help-function def)))))
+ (help-xref-button 1 'help-function real-def)))))
- (setq file-name (find-lisp-object-file-name function def))
(when file-name
(princ " in `")
;; We used to add .el to the file name,
@@ -531,11 +553,21 @@ suitable file is found, return nil."
(unless (looking-back "\n\n")
(terpri)))))
(help-fns--compiler-macro function)
- (let* ((advertised (gethash def advertised-signature-table t))
+ (let* ((advertised (gethash real-def advertised-signature-table t))
(arglist (if (listp advertised)
- advertised (help-function-arglist def)))
- (doc (condition-case err (documentation function)
- (error (format "No Doc! %S" err))))
+ advertised (help-function-arglist real-def)))
+ (doc-raw (condition-case err
+ (documentation function t)
+ (error (format "No Doc! %S" err))))
+ ;; If the function is autoloaded, and its docstring has
+ ;; key substitution constructs, load the library.
+ (doc (progn
+ (and (eq (car-safe real-def) 'autoload)
+ help-enable-auto-load
+ (string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]"
+ doc-raw)
+ (load (cadr real-def) t))
+ (substitute-command-keys doc-raw)))
(usage (help-split-fundoc doc function)))
(with-current-buffer standard-output
;; If definition is a keymap, skip arglist note.
@@ -556,9 +588,9 @@ suitable file is found, return nil."
function)))))
usage)
(car usage))
- ((or (stringp def)
- (vectorp def))
- (format "\nMacro: %s" (format-kbd-macro def)))
+ ((or (stringp real-def)
+ (vectorp real-def))
+ (format "\nMacro: %s" (format-kbd-macro real-def)))
(t "[Missing arglist. Please make a bug report.]")))
(high (help-highlight-arguments use doc)))
(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'"
:group 'help
:version "23.1")
+(defcustom help-enable-auto-load t
+ "Whether Help commands can perform autoloading.
+If non-nil, whenever \\[describe-function] is called for an
+autoloaded function whose docstring contains any key substitution
+construct (see `substitute-command-keys'), the library is loaded,
+so that the documentation can show the right key bindings."
+ :type 'boolean
+ :group 'help
+ :version "24.2")
+
(defun help-window-display-message (quit-part window &optional scroll)
"Display message telling how to quit and scroll help window.
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 @@
+2012-06-27 Chong Yidong <cyd@gnu.org>
+
+ * doc.c (Fsubstitute_command_keys): Fix punctuation.
+
2012-06-26 John Wiegley <johnw@newartisans.com>
* 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. */)
if (NILP (tem))
{
name = Fsymbol_name (name);
- insert_string ("\nUses keymap \"");
+ insert_string ("\nUses keymap `");
insert_from_string (name, 0, 0,
SCHARS (name),
SBYTES (name), 1);
- insert_string ("\", which is not currently defined.\n");
+ insert_string ("', which is not currently defined.\n");
if (start[-1] == '<') keymap = Qnil;
}
else if (start[-1] == '<')