(mac-keyboard-modifier-mask-alist): New constant.
[bpt/emacs.git] / lisp / help.el
index 1661779..8aa9ba6 100644 (file)
@@ -1,7 +1,7 @@
 ;;; help.el --- help commands for Emacs
 
 ;; Copyright (C) 1985, 1986, 1993, 1994, 1998, 1999, 2000, 2001, 2002,
-;;   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+;;   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: help, internal
@@ -182,31 +182,28 @@ specifies what to do when the user exits the help buffer."
   "You have typed %THIS-KEY%, the help character.  Type a Help option:
 \(Use SPC or DEL to scroll through this text.  Type \\<help-map>\\[help-quit] to exit the Help command.)
 
-a  command-apropos.  Give a list of words or a regexp, to get a list of
+a  command-apropos.  Type a list of words or a regexp; it shows a list of
         commands whose names match.  See also the  apropos  command.
-b  describe-bindings.  Display table of all key bindings.
-c  describe-key-briefly.  Type a command key sequence;
-       it prints the function name that sequence runs.
-C  describe-coding-system.  This describes either a specific coding system
-        (if you type its name) or the coding systems currently in use
-       (if you type just RET).
-d  apropos-documentation.  Give a pattern (a list or words or a regexp), and
-       see a list of functions, variables, and other items whose built-in
-       doucmentation string matches that pattern.  See also the apropos command.
-e  view-echo-area-messages.  Show the buffer where the echo-area messages
-       are stored.
-f  describe-function.  Type a function name and get its documentation.
-F  Info-goto-emacs-command-node.  Type a function name;
-       it takes you to the on-line manual's section that describes
-       the command.
+b  describe-bindings.  Display a table of all key bindings.
+c  describe-key-briefly.  Type a key sequence;
+       it displays the command name run by that key sequence.
+C  describe-coding-system.  Type the name of the coding system to describe,
+        or just RET to describe the ones currently in use.
+d  apropos-documentation.  Type a pattern (a list of words or a regexp), and
+       it shows a list of functions, variables, and other items whose
+       documentation matches that pattern.  See also the apropos command.
+e  view-echo-area-messages.  Go to the buffer that logs echo-area messages.
+f  describe-function.  Type a function name and you see its documentation.
+F  Info-goto-emacs-command-node.  Type a command name;
+       it goes to the on-line manual's section that describes the command.
 h  Display the HELLO file which illustrates various scripts.
-i  info. The Info documentation reader: read on-line manuals.
+i  info.  The Info documentation reader: read on-line manuals.
 I  describe-input-method.  Describe a specific input method (if you type
        its name) or the current input method (if you type just RET).
-k  describe-key.  Type a command key sequence;
+k  describe-key.  Type a key sequence;
        it displays the full documentation for that key sequence.
-K Info-goto-emacs-key-command-node.  Type a command key sequence;
-       it takes you to the on-line manual's section that describes
+K  Info-goto-emacs-key-command-node.  Type a key sequence;
+       it goes to the on-line manual's section that describes
        the command bound to that key.
 l  view-lossage.  Show last 100 characters you typed.
 L  describe-language-environment.  This describes either a
@@ -218,12 +215,12 @@ n  view-emacs-news.  Display news of recent Emacs changes.
 p  finder-by-keyword. Find packages matching a given topic keyword.
 r  info-emacs-manual.  Display the Emacs manual in Info mode.
 s  describe-syntax.  Display contents of syntax table, plus explanations.
-S  info-lookup-symbol.  Display the definition of a specific symbol
-        as found in the manual for the language this buffer is written in.
+S  info-lookup-symbol.  Type a symbol; it goes to that symbol in the
+        on-line manual for the programming language used in this buffer.
 t  help-with-tutorial.  Select the Emacs learn-by-doing tutorial.
 v  describe-variable.  Type name of a variable;
        it displays the variable's documentation and value.
-w  where-is.  Type command name; it prints which keystrokes
+w  where-is.  Type a command name; it displays which keystrokes
        invoke that command.
 .  display-local-help.  Display any available local help at point
         in the echo area.
@@ -312,7 +309,7 @@ If that doesn't give a function, return nil."
 The prefix described consists of all but the last event
 of the key sequence that ran this command."
   (interactive)
-  (let* ((key (this-command-keys)))
+  (let ((key (this-command-keys)))
     (describe-bindings
      (if (stringp key)
         (substring key 0 (1- (length key)))
@@ -326,63 +323,76 @@ of the key sequence that ran this command."
 ;; run describe-prefix-bindings.
 (setq prefix-help-command 'describe-prefix-bindings)
 
-(defun view-emacs-news (&optional arg)
+(defun view-emacs-news (&optional version)
   "Display info on recent changes to Emacs.
 With argument, display info only for the selected version."
   (interactive "P")
-  (if (not arg)
-      (view-file (expand-file-name "NEWS" data-directory))
-    (let* ((map (sort
-                 (delete-dups
-                  (apply
-                   'nconc
-                   (mapcar
-                    (lambda (file)
-                      (with-temp-buffer
-                        (insert-file-contents
-                         (expand-file-name file data-directory))
-                        (let (res)
-                          (while (re-search-forward
-                                  (if (string-match "^ONEWS\\.[0-9]+$" file)
-                                      "Changes in \\(?:Emacs\\|version\\)?[ \t]*\\([0-9]+\\(?:\\.[0-9]+\\)?\\)"
-                                    "^\* [^0-9\n]*\\([0-9]+\\.[0-9]+\\)") nil t)
-                            (setq res (cons (list (match-string-no-properties 1)
-                                                  file) res)))
-                          res)))
-                    (append '("NEWS" "ONEWS")
-                            (directory-files data-directory nil
-                                             "^ONEWS\\.[0-9]+$" nil)))))
-                 (lambda (a b)
-                   (string< (car b) (car a)))))
-           (current (caar map))
-           (version (completing-read
-                     (format "Read NEWS for the version (default %s): " current)
-                     (mapcar 'car map) nil nil nil nil current))
-           (file (cadr (assoc version map)))
-           res)
-      (if (not file)
-          (error "No news is good news")
-        (view-file (expand-file-name file data-directory))
-        (widen)
-        (goto-char (point-min))
-        (when (re-search-forward
-               (concat (if (string-match "^ONEWS\\.[0-9]+$" file)
-                           "Changes in \\(?:Emacs\\|version\\)?[ \t]*"
-                         "^\* [^0-9\n]*") version)
-               nil t)
-          (beginning-of-line)
-          (narrow-to-region
-           (point)
-           (save-excursion
-             (while (and (setq res
-                               (re-search-forward
-                                (if (string-match "^ONEWS\\.[0-9]+$" file)
-                                    "Changes in \\(?:Emacs\\|version\\)?[ \t]*\\([0-9]+\\(?:\\.[0-9]+\\)?\\)"
-                                  "^\* [^0-9\n]*\\([0-9]+\\.[0-9]+\\)") nil t))
-                         (equal (match-string-no-properties 1) version)))
-             (or res (goto-char (point-max)))
-             (beginning-of-line)
-             (point))))))))
+  (unless version
+    (setq version emacs-major-version))
+  (when (consp version)
+    (let* ((all-versions
+           (let (res)
+             (mapcar
+              (lambda (file)
+                (with-temp-buffer
+                  (insert-file-contents
+                   (expand-file-name file data-directory))
+                  (while (re-search-forward
+                          (if (member file '("NEWS.18" "NEWS.1-17"))
+                              "Changes in \\(?:Emacs\\|version\\)?[ \t]*\\([0-9]+\\(?:\\.[0-9]+\\)?\\)"
+                            "^\* [^0-9\n]*\\([0-9]+\\.[0-9]+\\)") nil t)
+                    (setq res (cons (match-string-no-properties 1) res)))))
+              (cons "NEWS"
+                    (directory-files data-directory nil
+                                     "^NEWS\\.[0-9][-0-9]*$" nil)))
+             (sort (delete-dups res) (lambda (a b) (string< b a)))))
+          (current (car all-versions)))
+      (setq version (completing-read
+                    (format "Read NEWS for the version (default %s): " current)
+                    all-versions nil nil nil nil current))
+      (if (integerp (string-to-number version))
+         (setq version (string-to-number version))
+       (unless (or (member version all-versions)
+                   (<= (string-to-number version) (string-to-number current)))
+         (error "No news about version %s" version)))))
+  (when (integerp version)
+    (cond ((<= version 12)
+          (setq version (format "1.%d" version)))
+         ((<= version 18)
+          (setq version (format "%d" version)))
+         ((> version emacs-major-version)
+          (error "No news about Emacs %d (yet)" version))))
+  (let* ((vn (if (stringp version)
+                (string-to-number version)
+              version))
+        (file (cond
+               ((>= vn emacs-major-version) "NEWS")
+               ((< vn 18) "NEWS.1-17")
+               (t (format "NEWS.%d" vn))))
+        res)
+    (view-file (expand-file-name file data-directory))
+    (widen)
+    (goto-char (point-min))
+    (when (stringp version)
+      (when (re-search-forward
+            (concat (if (< vn 19)
+                        "Changes in Emacs[ \t]*"
+                      "^\* [^0-9\n]*") version "$")
+            nil t)
+       (beginning-of-line)
+       (narrow-to-region
+        (point)
+        (save-excursion
+          (while (and (setq res
+                            (re-search-forward
+                             (if (< vn 19)
+                                 "Changes in \\(?:Emacs\\|version\\)?[ \t]*\\([0-9]+\\(?:\\.[0-9]+\\)?\\)"
+                               "^\* [^0-9\n]*\\([0-9]+\\.[0-9]+\\)") nil t))
+                      (equal (match-string-no-properties 1) version)))
+          (or res (goto-char (point-max)))
+          (beginning-of-line)
+          (point)))))))
+
 
 (defun view-todo (&optional arg)
   "Display the Emacs TODO list."
@@ -525,28 +535,6 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer."
          (princ string)))))
   nil)
 
-(defun string-key-binding (key)
-  "Value is the binding of KEY in a string.
-If KEY is an event on a string, and that string has a `local-map'
-or `keymap' property, return the binding of KEY in the string's keymap."
-  (let* ((defn nil)
-        (start (when (vectorp key)
-                 (if (memq (aref key 0)
-                           '(mode-line header-line left-margin right-margin))
-                     (event-start (aref key 1))
-                   (and (consp (aref key 0))
-                        (event-start (aref key 0))))))
-        (string-info (and (consp start) (nth 4 start))))
-    (when string-info
-      (let* ((string (car string-info))
-            (pos (cdr string-info))
-            (local-map (and (>= pos 0)
-                            (< pos (length string))
-                            (or (get-text-property pos 'local-map string)
-                                (get-text-property pos 'keymap string)))))
-       (setq defn (and local-map (lookup-key local-map key)))))
-    defn))
-
 (defun help-key-description (key untranslated)
   (let ((string (key-description key)))
     (if (or (not untranslated)
@@ -579,11 +567,14 @@ temporarily enables it to allow getting help on disabled items and buttons."
             (menu-bar-update-yank-menu "(any string)" nil))
           (setq key (read-key-sequence "Describe key (or click or menu item): "))
           ;; If KEY is a down-event, read and discard the
-          ;; corresponding up-event.
-          (if (and (vectorp key)
-                   (eventp (elt key 0))
-                   (memq 'down (event-modifiers (elt key 0))))
-              (read-event))
+          ;; corresponding up-event.  Note that there are also
+          ;; down-events on scroll bars and mode lines: the actual
+          ;; event then is in the second element of the vector.
+          (and (vectorp key)
+               (let ((last-idx (1- (length key))))
+                 (and (eventp (aref key last-idx))
+                      (memq 'down (event-modifiers (aref key last-idx)))))
+               (read-event))
           (list
            key
            (if current-prefix-arg (prefix-numeric-value current-prefix-arg))
@@ -594,46 +585,33 @@ temporarily enables it to allow getting help on disabled items and buttons."
         (fset 'yank-menu (cons 'keymap yank-menu))))))
   (if (numberp untranslated)
       (setq untranslated (this-single-command-raw-keys)))
-  (save-excursion
-    (let ((modifiers (event-modifiers (aref key 0)))
-         (standard-output (if insert (current-buffer) t))
-         window position)
-      ;; For a mouse button event, go to the button it applies to
-      ;; to get the right key bindings.  And go to the right place
-      ;; in case the keymap depends on where you clicked.
-      (if (or (memq 'click modifiers) (memq 'down modifiers)
-             (memq 'drag modifiers))
-         (setq window (posn-window (event-start (aref key 0)))
-               position (posn-point (event-start (aref key 0)))))
-      (if (windowp window)
-         (progn
-           (set-buffer (window-buffer window))
-           (goto-char position)))
-      ;; Ok, now look up the key and name the command.
-      (let ((defn (or (string-key-binding key)
-                     (key-binding key t)))
-           key-desc)
-       ;; Handle the case where we faked an entry in "Select and Paste" menu.
-       (if (and (eq defn nil)
-                (stringp (aref key (1- (length key))))
-                (eq (key-binding (substring key 0 -1)) 'yank-menu))
-           (setq defn 'menu-bar-select-yank))
-       ;; Don't bother user with strings from (e.g.) the select-paste menu.
-       (if (stringp (aref key (1- (length key))))
-           (aset key (1- (length key)) "(any string)"))
-       (if (and (> (length untranslated) 0)
-                (stringp (aref untranslated (1- (length untranslated)))))
-           (aset untranslated (1- (length untranslated))
-                 "(any string)"))
-       ;; Now describe the key, perhaps as changed.
-       (setq key-desc (help-key-description key untranslated))
-       (if (or (null defn) (integerp defn) (equal defn 'undefined))
-           (princ (format "%s is undefined" key-desc))
-         (princ (format (if (windowp window)
-                            "%s at that spot runs the command %s"
-                          "%s runs the command %s")
-                        key-desc
-                        (if (symbolp defn) defn (prin1-to-string defn)))))))))
+  (let* ((event (if (and (symbolp (aref key 0))
+                        (> (length key) 1)
+                        (consp (aref key 1)))
+                   (aref key 1)
+                 (aref key 0)))
+        (modifiers (event-modifiers event))
+        (standard-output (if insert (current-buffer) t))
+        (mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers)
+                           (memq 'drag modifiers)) " at that spot" ""))
+        (defn (key-binding key t))
+        key-desc)
+    ;; Handle the case where we faked an entry in "Select and Paste" menu.
+    (if (and (eq defn nil)
+            (stringp (aref key (1- (length key))))
+            (eq (key-binding (substring key 0 -1)) 'yank-menu))
+       (setq defn 'menu-bar-select-yank))
+    ;; Don't bother user with strings from (e.g.) the select-paste menu.
+    (if (stringp (aref key (1- (length key))))
+       (aset key (1- (length key)) "(any string)"))
+    (if (and (> (length untranslated) 0)
+            (stringp (aref untranslated (1- (length untranslated)))))
+       (aset untranslated (1- (length untranslated)) "(any string)"))
+    ;; Now describe the key, perhaps as changed.
+    (setq key-desc (help-key-description key untranslated))
+    (if (or (null defn) (integerp defn) (equal defn 'undefined))
+       (princ (format "%s%s is undefined" key-desc mouse-msg))
+      (princ (format "%s%s runs the command %S" key-desc mouse-msg defn)))))
 
 (defun describe-key (&optional key untranslated up-event)
   "Display documentation of the function invoked by KEY.
@@ -663,109 +641,119 @@ temporarily enables it to allow getting help on disabled items and buttons."
           (list
            key
            (prefix-numeric-value current-prefix-arg)
-           ;; If KEY is a down-event, read the corresponding up-event
-           ;; and use it as the third argument.
-           (if (and (vectorp key)
-                    (eventp (elt key 0))
-                    (memq 'down (event-modifiers (elt key 0))))
-               (read-event))))
+           ;; If KEY is a down-event, read and discard the
+           ;; corresponding up-event.  Note that there are also
+           ;; down-events on scroll bars and mode lines: the actual
+           ;; event then is in the second element of the vector.
+           (and (vectorp key)
+                (let ((last-idx (1- (length key))))
+                  (and (eventp (aref key last-idx))
+                       (memq 'down (event-modifiers (aref key last-idx)))))
+                (or (and (eventp (aref key 0))
+                         (memq 'down (event-modifiers (aref key 0)))
+                         ;; However, for the C-down-mouse-2 popup
+                         ;; menu, there is no subsequent up-event.  In
+                         ;; this case, the up-event is the next
+                         ;; element in the supplied vector.
+                         (= (length key) 1))
+                    (and (> (length key) 1)
+                         (eventp (aref key 1))
+                         (memq 'down (event-modifiers (aref key 1)))))
+                (read-event))))
        ;; Put yank-menu back as it was, if we changed it.
        (when saved-yank-menu
         (setq yank-menu (copy-sequence saved-yank-menu))
         (fset 'yank-menu (cons 'keymap yank-menu))))))
   (if (numberp untranslated)
       (setq untranslated (this-single-command-raw-keys)))
-  (save-excursion
-    (let ((modifiers (event-modifiers (aref key 0)))
-         window position)
-      ;; For a mouse button event, go to the button it applies to
-      ;; to get the right key bindings.  And go to the right place
-      ;; in case the keymap depends on where you clicked.
-      (if (or (memq 'click modifiers) (memq 'down modifiers)
-             (memq 'drag modifiers))
-         (setq window (posn-window (event-start (aref key 0)))
-               position (posn-point (event-start (aref key 0)))))
-      (when (windowp window)
-           (set-buffer (window-buffer window))
-       (goto-char position))
-      (let ((defn (or (string-key-binding key) (key-binding key t))))
-       ;; Handle the case where we faked an entry in "Select and Paste" menu.
-       (if (and (eq defn nil)
-                (stringp (aref key (1- (length key))))
-                (eq (key-binding (substring key 0 -1)) 'yank-menu))
-           (setq defn 'menu-bar-select-yank))
-       (if (or (null defn) (integerp defn) (equal defn 'undefined))
-           (message "%s is undefined" (help-key-description key untranslated))
-         (help-setup-xref (list #'describe-function defn) (interactive-p))
-         ;; Don't bother user with strings from (e.g.) the select-paste menu.
-         (if (stringp (aref key (1- (length key))))
-             (aset key (1- (length key)) "(any string)"))
-         (if (and untranslated
-                  (stringp (aref untranslated (1- (length untranslated)))))
-             (aset untranslated (1- (length untranslated))
-                   "(any string)"))
-         (with-output-to-temp-buffer (help-buffer)
-           (princ (help-key-description key untranslated))
-           (if (windowp window)
-               (princ " at that spot"))
-           (princ " runs the command ")
-           (prin1 defn)
-           (princ "\n   which is ")
-           (describe-function-1 defn)
-           (when up-event
-             (let ((type (event-basic-type up-event))
-                   (hdr "\n\n-------------- up event ---------------\n\n")
-                   defn sequence
-                   mouse-1-tricky mouse-1-remapped)
-               (setq sequence (vector up-event))
-               (when (and (eq type 'mouse-1)
-                          (windowp window)
+  (let* ((event (aref key (if (and (symbolp (aref key 0))
+                                  (> (length key) 1)
+                                  (consp (aref key 1)))
+                             1
+                           0)))
+        (modifiers (event-modifiers event))
+        (mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers)
+                           (memq 'drag modifiers)) " at that spot" ""))
+        (defn (key-binding key t))
+        defn-up defn-up-tricky ev-type
+        mouse-1-remapped mouse-1-tricky)
+
+    ;; Handle the case where we faked an entry in "Select and Paste" menu.
+    (when (and (eq defn nil)
+              (stringp (aref key (1- (length key))))
+              (eq (key-binding (substring key 0 -1)) 'yank-menu))
+      (setq defn 'menu-bar-select-yank))
+    (if (or (null defn) (integerp defn) (equal defn 'undefined))
+       (message "%s%s is undefined"
+                (help-key-description key untranslated) mouse-msg)
+      (help-setup-xref (list #'describe-function defn) (interactive-p))
+      ;; Don't bother user with strings from (e.g.) the select-paste menu.
+      (when (stringp (aref key (1- (length key))))
+       (aset key (1- (length key)) "(any string)"))
+      (when (and untranslated
+                (stringp (aref untranslated (1- (length untranslated)))))
+       (aset untranslated (1- (length untranslated))
+             "(any string)"))
+      ;; Need to do this before erasing *Help* buffer in case event
+      ;; is a mouse click in an existing *Help* buffer.
+      (when up-event
+       (setq ev-type (event-basic-type up-event))
+       (let ((sequence (vector up-event)))
+         (when (and (eq ev-type 'mouse-1)
+                    mouse-1-click-follows-link
+                    (not (eq mouse-1-click-follows-link 'double))
+                    (setq mouse-1-remapped
+                          (mouse-on-link-p (event-start up-event))))
+           (setq mouse-1-tricky (and (integerp mouse-1-click-follows-link)
+                                     (> mouse-1-click-follows-link 0)))
+           (cond ((stringp mouse-1-remapped)
+                  (setq sequence mouse-1-remapped))
+                 ((vectorp mouse-1-remapped)
+                  (setcar up-event (elt mouse-1-remapped 0)))
+                 (t (setcar up-event 'mouse-2))))
+         (setq defn-up (key-binding sequence nil nil (event-start up-event)))
+         (when mouse-1-tricky
+           (setq sequence (vector up-event))
+           (aset sequence 0 'mouse-1)
+           (setq defn-up-tricky (key-binding sequence nil nil (event-start up-event))))))
+      (with-output-to-temp-buffer (help-buffer)
+       (princ (help-key-description key untranslated))
+       (princ (format "\
+%s runs the command %S
+  which is "
+                      mouse-msg defn))
+       (describe-function-1 defn)
+       (when up-event
+         (unless (or (null defn-up)
+                     (integerp defn-up)
+                     (equal defn-up 'undefined))
+           (princ (format "
+
+----------------- up-event %s----------------
+
+<%S>%s%s runs the command %S
+  which is "
+                          (if mouse-1-tricky "(short click) " "")
+                          ev-type mouse-msg
+                          (if mouse-1-remapped
+                              " is remapped to <mouse-2>\nwhich" "")
+                          defn-up))
+           (describe-function-1 defn-up))
+         (unless (or (null defn-up-tricky)
+                     (integerp defn-up-tricky)
+                     (eq defn-up-tricky 'undefined))
+           (princ (format "
+
+----------------- up-event (long click) ----------------
+
+Pressing <%S>%s for longer than %d milli-seconds
+runs the command %S
+  which is "
+                          ev-type mouse-msg
                           mouse-1-click-follows-link
-                          (not (eq mouse-1-click-follows-link 'double))
-                          (setq mouse-1-remapped
-                                (with-current-buffer (window-buffer window)
-                                  (mouse-on-link-p (posn-point
-                                                    (event-start up-event))))))
-                 (setq mouse-1-tricky (and (integerp mouse-1-click-follows-link)
-                                           (> mouse-1-click-follows-link 0)))
-                 (cond ((stringp mouse-1-remapped)
-                        (setq sequence mouse-1-remapped))
-                       ((vectorp mouse-1-remapped)
-                        (setcar up-event (elt mouse-1-remapped 0)))
-                       (t (setcar up-event 'mouse-2))))
-               (setq defn (or (string-key-binding sequence)
-                              (key-binding sequence)))
-               (unless (or (null defn) (integerp defn) (equal defn 'undefined))
-                 (princ (if mouse-1-tricky
-                            "\n\n----------------- up-event (short click) ----------------\n\n"
-                          hdr))
-                 (setq hdr nil)
-                 (princ (symbol-name type))
-                 (if (windowp window)
-                     (princ " at that spot"))
-                 (if mouse-1-remapped
-                     (princ " is remapped to <mouse-2>\n  which" ))
-                 (princ " runs the command ")
-                 (prin1 defn)
-                 (princ "\n   which is ")
-                 (describe-function-1 defn))
-               (when mouse-1-tricky
-                 (setcar up-event 'mouse-1)
-                 (setq defn (or (string-key-binding (vector up-event))
-                                (key-binding (vector up-event))))
-                 (unless (or (null defn) (integerp defn) (eq defn 'undefined))
-                   (princ (or hdr
-                              "\n\n----------------- up-event (long click) ----------------\n\n"))
-                   (princ "Pressing mouse-1")
-                   (if (windowp window)
-                       (princ " at that spot"))
-                   (princ (format " for longer than %d milli-seconds\n"
-                                  mouse-1-click-follows-link))
-                   (princ " runs the command ")
-                   (prin1 defn)
-                   (princ "\n   which is ")
-                   (describe-function-1 defn)))))
-           (print-help-return-message)))))))
+                          defn-up-tricky))
+           (describe-function-1 defn-up-tricky)))
+       (print-help-return-message)))))
 \f
 (defun describe-mode (&optional buffer)
   "Display documentation of current major mode and minor modes.
@@ -776,7 +764,7 @@ descriptions of the minor modes, each on a separate page.
 For this to work correctly for a minor mode, the mode's indicator
 variable \(listed in `minor-mode-alist') must also be a function
 whose documentation describes the minor mode."
-  (interactive)
+  (interactive "@")
   (unless buffer (setq buffer (current-buffer)))
   (help-setup-xref (list #'describe-mode buffer)
                   (interactive-p))
@@ -812,16 +800,13 @@ whose documentation describes the minor mode."
              (sort minor-modes
                    (lambda (a b) (string-lessp (cadr a) (cadr b)))))
        (when minor-modes
-         (princ "Summary of minor modes:\n")
+         (princ "Enabled minor modes:\n")
          (make-local-variable 'help-button-cache)
          (with-current-buffer standard-output
            (dolist (mode minor-modes)
              (let ((mode-function (nth 0 mode))
                    (pretty-minor-mode (nth 1 mode))
                    (indicator (nth 2 mode)))
-               (setq indicator (if (zerop (length indicator))
-                                   "no indicator"
-                                 (format "indicator%s" indicator)))
                (add-text-properties 0 (length pretty-minor-mode)
                                     '(face bold) pretty-minor-mode)
                (save-excursion
@@ -830,16 +815,22 @@ whose documentation describes the minor mode."
                  (push (point-marker) help-button-cache)
                  ;; Document the minor modes fully.
                  (insert pretty-minor-mode)
-                 (princ (format " minor mode (%s):\n" indicator))
+                 (princ (format " minor mode (%s):\n"
+                                (if (zerop (length indicator))
+                                    "no indicator"
+                                  (format "indicator%s"
+                                          indicator))))
                  (princ (documentation mode-function)))
-               (princ "  ")
                (insert-button pretty-minor-mode
                               'action (car help-button-cache)
                               'follow-link t
                               'help-echo "mouse-2, RET: show full information")
-               (princ (format " minor mode (%s):\n" indicator)))))
-         (princ "\n(Full information about these minor modes
-follows the description of the major mode.)\n\n"))
+               (newline)))
+           (forward-line -1)
+           (fill-paragraph nil)
+           (forward-line 1))
+
+         (princ "\n(Information about these minor modes follows the major mode info.)\n\n"))
        ;; Document the major mode.
        (let ((mode mode-name))
          (with-current-buffer standard-output
@@ -896,7 +887,7 @@ appeared on the mode-line."
                    (cond
                     ((= 0 (length i))
                      nil)
-                    ((eq (aref i 0) ?\ )
+                    ((eq (aref i 0) ?\s)
                      (substring i 1))
                     (t
                      i))))
@@ -918,7 +909,7 @@ is currently activated with completion."
   "Return a minor mode symbol from its indicator on the modeline."
   ;; remove first space if existed
   (if (and (< 0 (length indicator))
-          (eq (aref indicator 0) ?\ ))
+          (eq (aref indicator 0) ?\s))
       (setq indicator (substring indicator 1)))
   (let ((minor-modes minor-mode-alist)
        result)
@@ -929,7 +920,7 @@ is currently activated with completion."
        ;; remove first space if existed
        (if (and (stringp anindicator)
                 (> (length anindicator) 0)
-                (eq (aref anindicator 0) ?\ ))
+                (eq (aref anindicator 0) ?\s))
            (setq anindicator (substring anindicator 1)))
        (if (equal indicator anindicator)
            (setq result minor-mode
@@ -942,11 +933,11 @@ is currently activated with completion."
 
 (defcustom temp-buffer-max-height (lambda (buffer) (/ (- (frame-height) 2) 2))
   "Maximum height of a window displaying a temporary buffer.
-This is the maximum height (in text lines) which `resize-temp-buffer-window'
+This is effective only when Temp Buffer Resize mode is enabled.
+The value is the maximum height (in lines) which `resize-temp-buffer-window'
 will give to a window displaying a temporary buffer.
-It can also be a function which will be called with the object corresponding
-to the buffer to be displayed as argument and should return an integer
-positive number."
+It can also be a function to be called to choose the height for such a buffer.
+It gets one argumemt, the buffer, and should return a positive integer."
   :type '(choice integer function)
   :group 'help
   :version "20.4")