(describe-mode): Make minor mode list more concise.
[bpt/emacs.git] / lisp / help.el
index 5141c06..af79bbc 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 Free Software Foundation, Inc.
+;;   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: help, internal
 (add-hook 'temp-buffer-setup-hook 'help-mode-setup)
 (add-hook 'temp-buffer-show-hook 'help-mode-finish)
 
-(defvar help-map (make-sparse-keymap)
+(defvar help-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (char-to-string help-char) 'help-for-help)
+    (define-key map [help] 'help-for-help)
+    (define-key map [f1] 'help-for-help)
+    (define-key map "." 'display-local-help)
+    (define-key map "?" 'help-for-help)
+
+    (define-key map "\C-c" 'describe-copying)
+    (define-key map "\C-d" 'describe-distribution)
+    (define-key map "\C-e" 'view-emacs-problems)
+    (define-key map "\C-f" 'view-emacs-FAQ)
+    (define-key map "\C-m" 'view-order-manuals)
+    (define-key map "\C-n" 'view-emacs-news)
+    (define-key map "\C-p" 'describe-project)
+    (define-key map "\C-t" 'view-todo)
+    (define-key map "\C-w" 'describe-no-warranty)
+
+    ;; This does not fit the pattern, but it is natural given the C-\ command.
+    (define-key map "\C-\\" 'describe-input-method)
+
+    (define-key map "C" 'describe-coding-system)
+    (define-key map "F" 'Info-goto-emacs-command-node)
+    (define-key map "I" 'describe-input-method)
+    (define-key map "K" 'Info-goto-emacs-key-command-node)
+    (define-key map "L" 'describe-language-environment)
+    (define-key map "S" 'info-lookup-symbol)
+
+    (define-key map "a" 'apropos-command)
+    (define-key map "b" 'describe-bindings)
+    (define-key map "c" 'describe-key-briefly)
+    (define-key map "d" 'apropos-documentation)
+    (define-key map "e" 'view-echo-area-messages)
+    (define-key map "f" 'describe-function)
+    (define-key map "h" 'view-hello-file)
+
+    (define-key map "i" 'info)
+    (define-key map "4i" 'info-other-window)
+
+    (define-key map "k" 'describe-key)
+    (define-key map "l" 'view-lossage)
+    (define-key map "m" 'describe-mode)
+    (define-key map "n" 'view-emacs-news)
+    (define-key map "p" 'finder-by-keyword)
+    (define-key map "r" 'info-emacs-manual)
+    (define-key map "s" 'describe-syntax)
+    (define-key map "t" 'help-with-tutorial)
+    (define-key map "w" 'where-is)
+    (define-key map "v" 'describe-variable)
+    (define-key map "q" 'help-quit)
+    map)
   "Keymap for characters following the Help key.")
 
 (define-key global-map (char-to-string help-char) 'help-command)
 (define-key global-map [f1] 'help-command)
 (fset 'help-command help-map)
 
-(define-key help-map (char-to-string help-char) 'help-for-help)
-(define-key help-map [help] 'help-for-help)
-(define-key help-map [f1] 'help-for-help)
-(define-key help-map "." 'display-local-help)
-(define-key help-map "?" 'help-for-help)
-
-(define-key help-map "\C-c" 'describe-copying)
-(define-key help-map "\C-d" 'describe-distribution)
-(define-key help-map "\C-e" 'view-emacs-problems)
-(define-key help-map "\C-f" 'view-emacs-FAQ)
-(define-key help-map "\C-m" 'view-order-manuals)
-(define-key help-map "\C-n" 'view-emacs-news)
-(define-key help-map "\C-p" 'describe-project)
-(define-key help-map "\C-t" 'view-todo)
-(define-key help-map "\C-w" 'describe-no-warranty)
-
-;; This does not fit the pattern, but it is natural given the C-\ command.
-(define-key help-map "\C-\\" 'describe-input-method)
-
-(define-key help-map "C" 'describe-coding-system)
-(define-key help-map "F" 'Info-goto-emacs-command-node)
-(define-key help-map "I" 'describe-input-method)
-(define-key help-map "K" 'Info-goto-emacs-key-command-node)
-(define-key help-map "L" 'describe-language-environment)
-(define-key help-map "S" 'info-lookup-symbol)
-
-(define-key help-map "a" 'apropos-command)
-
-(define-key help-map "b" 'describe-bindings)
-
-(define-key help-map "c" 'describe-key-briefly)
-
-(define-key help-map "d" 'apropos-documentation)
-
-(define-key help-map "e" 'view-echo-area-messages)
-
-(define-key help-map "f" 'describe-function)
-
-(define-key help-map "h" 'view-hello-file)
-
-(define-key help-map "i" 'info)
-(define-key help-map "4i" 'info-other-window)
-
-(define-key help-map "k" 'describe-key)
-
-(define-key help-map "l" 'view-lossage)
-
-(define-key help-map "m" 'describe-mode)
-
-(define-key help-map "n" 'view-emacs-news)
-
-(define-key help-map "p" 'finder-by-keyword)
 (autoload 'finder-by-keyword "finder"
   "Find packages matching a given keyword." t)
 
-(define-key help-map "r" 'info-emacs-manual)
-
-(define-key help-map "s" 'describe-syntax)
-
-(define-key help-map "t" 'help-with-tutorial)
-
-(define-key help-map "w" 'where-is)
-
-(define-key help-map "v" 'describe-variable)
-
-(define-key help-map "q" 'help-quit)
-
 ;; insert-button makes the action nil if it is not store somewhere
 (defvar help-button-cache nil)
 
 (defvar help-return-method nil
   "What to do to \"exit\" the help buffer.
 This is a list
- (WINDOW . t)              delete the selected window, go to WINDOW.
+ (WINDOW . t)              delete the selected window (and possibly its frame,
+                           see `quit-window' and `View-quit'), go to WINDOW.
  (WINDOW . quit-window)    do quit-window, then select WINDOW.
  (WINDOW BUF START POINT)  display BUF at START, POINT, then select WINDOW.")
 
@@ -133,10 +120,14 @@ This is a list
   "Display or return message saying how to restore windows after help command.
 This function assumes that `standard-output' is the help buffer.
 It computes a message, and applies the optional argument FUNCTION to it.
-If FUNCTION is nil, it applies `message', thus displaying the message."
+If FUNCTION is nil, it applies `message', thus displaying the message.
+In addition, this function sets up `help-return-method', which see, that
+specifies what to do when the user exits the help buffer."
   (and (not (get-buffer-window standard-output))
        (let ((first-message
-             (cond ((special-display-p (buffer-name standard-output))
+             (cond ((or
+                     pop-up-frames
+                     (special-display-p (buffer-name standard-output)))
                     (setq help-return-method (cons (selected-window) t))
                     ;; If the help output buffer is a special display buffer,
                     ;; don't say anything about how to get rid of it.
@@ -152,7 +143,7 @@ If FUNCTION is nil, it applies `message', thus displaying the message."
                    ((not (one-window-p t))
                     (setq help-return-method
                           (cons (selected-window) 'quit-window))
-                    "Type \\[switch-to-buffer-other-window] RET to restore the other window.")
+                    "Type \\[display-buffer] RET to restore the other window.")
                    (pop-up-windows
                     (setq help-return-method (cons (selected-window) t))
                     "Type \\[delete-other-windows] to remove help window.")
@@ -168,7 +159,8 @@ If FUNCTION is nil, it applies `message', thus displaying the message."
                   (if first-message "  ")
                   ;; If the help buffer will go in a separate frame,
                   ;; it's no use mentioning a command to scroll, so don't.
-                  (if (special-display-p (buffer-name standard-output))
+                  (if (or pop-up-windows
+                          (special-display-p (buffer-name standard-output)))
                       nil
                     (if (same-window-p (buffer-name standard-output))
                         ;; Say how to scroll this window.
@@ -186,36 +178,32 @@ If FUNCTION is nil, it applies `message', thus displaying the message."
 (defalias 'help-for-help 'help-for-help-internal)
 ;; It can't find this, but nobody will look.
 (make-help-screen help-for-help-internal
-  "a b c C e f F i I k C-k l L m p s t v w C-c C-d C-f C-n C-p C-t C-w . or ? :"
+  "a b c C e f F i I k C-k l L m p s t v w C-c C-d C-f C-n C-p C-t C-w . or ? :"
   "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
-        commands whose names match (they contain two or more of the words,
-       or a match for the regexp).  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.
+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 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
@@ -225,13 +213,14 @@ m  describe-mode.  Display documentation of current minor modes,
        and the current major mode, including their special commands.
 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.
@@ -334,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."
@@ -437,8 +439,9 @@ To record all your input on a file, use `open-dribble-file'."
     (with-current-buffer standard-output
       (goto-char (point-min))
       (while (progn (move-to-column 50) (not (eobp)))
-       (search-forward " " nil t)
-       (insert "\n")))
+        (when (search-forward " " nil t)
+          (delete-char -1))
+        (insert "\n")))
     (print-help-return-message)))
 
 \f
@@ -518,7 +521,7 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer."
                (if (> (length keys) 0)
                    (if remapped
                        (format "%s is remapped to %s which is on %s"
-                               definition symbol keys)
+                               symbol remapped keys)
                      (format "%s is on %s" symbol keys))
                  ;; If this is the command the user asked about,
                  ;; and it is not on any key, say so.
@@ -564,13 +567,41 @@ or `keymap' property, return the binding of KEY in the string's keymap."
            string
          (format "%s (translated from %s)" string otherstring))))))
 
-(defun describe-key-briefly (key &optional insert untranslated)
+(defun describe-key-briefly (&optional key insert untranslated)
   "Print the name of the function KEY invokes.  KEY is a string.
 If INSERT (the prefix arg) is non-nil, insert the message in the buffer.
-If non-nil UNTRANSLATED is a vector of the untranslated events.
+If non-nil, UNTRANSLATED is a vector of the untranslated events.
 It can also be a number in which case the untranslated events from
-the last key hit are used."
-  (interactive "kDescribe key briefly: \nP\np")
+the last key hit are used.
+
+If KEY is a menu item or a tool-bar button that is disabled, this command
+temporarily enables it to allow getting help on disabled items and buttons."
+  (interactive
+   (let ((enable-disabled-menus-and-buttons t)
+        (cursor-in-echo-area t)
+        saved-yank-menu)
+     (unwind-protect
+        (let (key)
+          ;; If yank-menu is empty, populate it temporarily, so that
+          ;; "Select and Paste" menu can generate a complete event.
+          (when (null (cdr yank-menu))
+            (setq saved-yank-menu (copy-sequence yank-menu))
+            (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))
+          (list
+           key
+           (if current-prefix-arg (prefix-numeric-value current-prefix-arg))
+           1))
+       ;; 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
@@ -590,8 +621,13 @@ the last key hit are used."
            (goto-char position)))
       ;; Ok, now look up the key and name the command.
       (let ((defn (or (string-key-binding key)
-                     (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)"))
@@ -609,17 +645,44 @@ the last key hit are used."
                         key-desc
                         (if (symbolp defn) defn (prin1-to-string defn)))))))))
 
-(defun describe-key (key &optional untranslated up-event)
+(defun describe-key (&optional key untranslated up-event)
   "Display documentation of the function invoked by KEY.
 KEY can be any kind of a key sequence; it can include keyboard events,
 mouse events, and/or menu events.  When calling from a program,
 pass KEY as a string or a vector.
 
-If non-nil, UNTRANSLATED is a vector of the correspondinguntranslated events.
+If non-nil, UNTRANSLATED is a vector of the corresponding untranslated events.
 It can also be a number, in which case the untranslated events from
-the last key sequence entered are used."
-  ;; UP-EVENT is the up-event that was discarded by reading KEY, or nil.
-  (interactive "kDescribe key (or click or menu item): \np\nU")
+the last key sequence entered are used.
+UP-EVENT is the up-event that was discarded by reading KEY, or nil.
+
+If KEY is a menu item or a tool-bar button that is disabled, this command
+temporarily enables it to allow getting help on disabled items and buttons."
+  (interactive
+   (let ((enable-disabled-menus-and-buttons t)
+        (cursor-in-echo-area t)
+        saved-yank-menu)
+     (unwind-protect
+        (let (key)
+          ;; If yank-menu is empty, populate it temporarily, so that
+          ;; "Select and Paste" menu can generate a complete event.
+          (when (null (cdr yank-menu))
+            (setq saved-yank-menu (copy-sequence yank-menu))
+            (menu-bar-update-yank-menu "(any string)" nil))
+          (setq key (read-key-sequence "Describe key (or click or menu item): "))
+          (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))))
+       ;; 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
@@ -635,7 +698,12 @@ the last key sequence entered are used."
       (when (windowp window)
            (set-buffer (window-buffer window))
        (goto-char position))
-      (let ((defn (or (string-key-binding key) (key-binding key))))
+      (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))
@@ -655,30 +723,34 @@ the last key sequence entered are used."
            (princ "\n   which is ")
            (describe-function-1 defn)
            (when up-event
-             (let ((ev (aref up-event 0))
-                   (descr (key-description up-event))
+             (let ((type (event-basic-type up-event))
                    (hdr "\n\n-------------- up event ---------------\n\n")
-                   defn
+                   defn sequence
                    mouse-1-tricky mouse-1-remapped)
-               (when (and (consp ev)
-                          (eq (car ev) 'mouse-1)
+               (setq sequence (vector up-event))
+               (when (and (eq type 'mouse-1)
                           (windowp window)
                           mouse-1-click-follows-link
                           (not (eq mouse-1-click-follows-link 'double))
-                          (with-current-buffer (window-buffer window)
-                            (mouse-on-link-p (posn-point (event-start ev)))))
-                 (setq mouse-1-tricky (integerp mouse-1-click-follows-link)
-                       mouse-1-remapped (or (not mouse-1-tricky)
-                                            (> mouse-1-click-follows-link 0)))
-                 (if mouse-1-remapped
-                     (setcar ev 'mouse-2)))
-               (setq defn (or (string-key-binding up-event) (key-binding up-event)))
+                          (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 descr)
+                 (princ (symbol-name type))
                  (if (windowp window)
                      (princ " at that spot"))
                  (if mouse-1-remapped
@@ -688,26 +760,22 @@ the last key sequence entered are used."
                  (princ "\n   which is ")
                  (describe-function-1 defn))
                (when mouse-1-tricky
-                 (setcar ev
-                         (if (> mouse-1-click-follows-link 0) 'mouse-1 'mouse-2))
-                 (setq defn (or (string-key-binding up-event) (key-binding up-event)))
-                 (unless (or (null defn) (integerp defn) (equal defn 'undefined))
+                 (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 ")
-                   (princ descr)
+                   (princ "Pressing mouse-1")
                    (if (windowp window)
                        (princ " at that spot"))
                    (princ (format " for longer than %d milli-seconds\n"
-                                  (abs mouse-1-click-follows-link)))
-                   (if (not mouse-1-remapped)
-                       (princ " remaps it to <mouse-2> which" ))
+                                  mouse-1-click-follows-link))
                    (princ " runs the command ")
                    (prin1 defn)
                    (princ "\n   which is ")
                    (describe-function-1 defn)))))
            (print-help-return-message)))))))
-
 \f
 (defun describe-mode (&optional buffer)
   "Display documentation of current major mode and minor modes.
@@ -754,16 +822,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
@@ -772,21 +837,28 @@ 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
-           (insert mode)
-           (add-text-properties (- (point) (length mode)) (point) '(face bold))))
+            (let ((start (point)))
+              (insert (format-mode-line mode))
+              (add-text-properties start (point) '(face bold)))))
        (princ " mode:\n")
        (princ (documentation major-mode)))
       (print-help-return-message))))
@@ -882,12 +954,12 @@ is currently activated with completion."
 ;;; Automatic resizing of temporary buffers.
 
 (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'
+  "Maximum height of a window displaying a temporary buffer.
+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")
@@ -921,8 +993,7 @@ out of view."
         (funcall temp-buffer-max-height (current-buffer))
        temp-buffer-max-height))))
 
-;; Provide this for the sake of define-minor-mode which generates
-;; defcustoms which require 'help'.
+\f
 (provide 'help)
 
 ;; arch-tag: cf427352-27e9-49b7-9a6f-741ebab02423