(org-set-tags): Keep single space after stars.
[bpt/emacs.git] / lisp / help.el
index cd95af0..4d92f69 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
 (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.")
 
@@ -119,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.
@@ -138,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.")
@@ -154,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.
@@ -172,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
@@ -211,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.
@@ -320,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."
@@ -423,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
@@ -504,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.
@@ -550,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
@@ -578,6 +623,11 @@ the last key hit are used."
       (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)"))
@@ -595,7 +645,7 @@ 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,
@@ -603,9 +653,36 @@ pass KEY as a string or a vector.
 
 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
@@ -622,6 +699,11 @@ the last key sequence entered are used."
            (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))
@@ -641,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
@@ -674,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.
@@ -771,8 +853,9 @@ follows the description of the major mode.)\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))))
@@ -868,12 +951,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")
@@ -907,8 +990,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