]> code.delx.au - gnu-emacs/blobdiff - lisp/info.el
(goto-address-mail-regexp): Allow = in username.
[gnu-emacs] / lisp / info.el
index 2a20fc4898c0b3b738316d007f82ad837d8620d5..750f302d4227ee28b024f8388b38591b77ebd688 100644 (file)
@@ -79,14 +79,14 @@ The Lisp code is executed when the node is selected.")
   :group 'info)
 
 (defface info-xref
-  '((((class color) (background light)) :foreground "blue")
-    (((class color) (background dark)) :foreground "cyan")
+  '((((class color) (background light)) :foreground "blue" :underline t)
+    (((class color) (background dark)) :foreground "cyan" :underline t)
     (t :underline t))
   "Face for Info cross-references."
   :group 'info)
 
 (defface info-xref-visited
-  '((t :inherit info-xref)
+  '((default :inherit info-xref)
     (((class color) (background light)) :foreground "magenta4")
     (((class color) (background dark)) :foreground "magenta3")) ;"violet"?
   "Face for visited Info cross-references."
@@ -188,7 +188,7 @@ file, so be prepared for a few surprises if you enable this feature."
   :type 'boolean
   :group 'info)
 
-(defcustom Info-search-whitespace-regexp "\\(?:\\s-+\\)"
+(defcustom Info-search-whitespace-regexp "\\s-+"
   "*If non-nil, regular expression to match a sequence of whitespace chars.
 This applies to Info search for regular expressions.
 You might want to use something like \"[ \\t\\r\\n]+\" instead.
@@ -455,6 +455,7 @@ Do the right thing if the file has been compressed or zipped."
 
 ;;;###autoload (add-hook 'same-window-regexps "\\*info\\*\\(\\|<[0-9]+>\\)")
 
+;;;###autoload (put 'info 'info-file "emacs")
 ;;;###autoload
 (defun info (&optional file buffer)
   "Enter Info, the documentation browser.
@@ -656,10 +657,10 @@ is preserved, if possible."
             (equal old-nodename Info-current-node))
        (progn
          ;; note goto-line is no good, we want to measure from point-min
-         (beginning-of-buffer)
+         (goto-char (point-min))
          (forward-line wline)
          (set-window-start (selected-window) (point))
-         (beginning-of-buffer)
+         (goto-char (point-min))
          (forward-line pline)
          (move-to-column pcolumn))
       ;; only add to the history when coming from a different file+node
@@ -1467,31 +1468,45 @@ If DIRECTION is `backward', search in the reverse direction."
          (opoint-max (point-max))
          (ostart (window-start))
          (osubfile Info-current-subfile))
-      (when Info-search-whitespace-regexp
-        (setq regexp
-              (mapconcat 'identity (split-string regexp "[ \t\n]+")
-                         Info-search-whitespace-regexp)))
       (setq Info-search-case-fold case-fold-search)
       (save-excursion
        (save-restriction
          (widen)
+         (when backward
+           ;; Hide Info file header for backward search
+           (narrow-to-region (save-excursion
+                               (goto-char (point-min))
+                               (search-forward "\n\^_")
+                               (1- (point)))
+                             (point-max)))
          (while (and (not give-up)
-                     (or (null found)
-                         (if backward
-                              (isearch-range-invisible found beg-found)
-                            (isearch-range-invisible beg-found found))))
-           (if (if backward
-                    (re-search-backward regexp bound t)
-                  (re-search-forward regexp bound t))
-               (setq found (point) beg-found (if backward (match-end 0)
-                                                (match-beginning 0)))
-             (setq give-up t)))))
+                     (save-match-data
+                       (or (null found)
+                           (if backward
+                               (isearch-range-invisible found beg-found)
+                             (isearch-range-invisible beg-found found))
+                           ;; Skip node header line
+                           (and (save-excursion (forward-line -1)
+                                                (looking-at "\^_"))
+                                (forward-line 1))
+                           ;; Skip Tag Table node
+                           (save-excursion
+                             (and (search-backward "\^_" nil t)
+                                  (looking-at "\^_\nTag Table"))))))
+           (let ((search-spaces-regexp Info-search-whitespace-regexp))
+             (if (if backward
+                     (re-search-backward regexp bound t)
+                   (re-search-forward regexp bound t))
+                 (setq found (point) beg-found (if backward (match-end 0)
+                                                 (match-beginning 0)))
+               (setq give-up t))))))
       ;; If no subfiles, give error now.
       (if give-up
          (if (null Info-current-subfile)
-             (if backward
-                  (re-search-backward regexp)
-                (re-search-forward regexp))
+             (let ((search-spaces-regexp Info-search-whitespace-regexp))
+               (if backward
+                   (re-search-backward regexp)
+                 (re-search-forward regexp)))
            (setq found nil)))
 
       (unless (or found bound)
@@ -1530,20 +1545,37 @@ If DIRECTION is `backward', search in the reverse direction."
              (while list
                (message "Searching subfile %s..." (cdr (car list)))
                (Info-read-subfile (car (car list)))
-                (if backward (goto-char (point-max)))
+               (when backward
+                 ;; Hide Info file header for backward search
+                 (narrow-to-region (save-excursion
+                                     (goto-char (point-min))
+                                     (search-forward "\n\^_")
+                                     (1- (point)))
+                                   (point-max))
+                 (goto-char (point-max)))
                (setq list (cdr list))
                (setq give-up nil found nil)
                (while (and (not give-up)
-                           (or (null found)
-                               (if backward
-                                    (isearch-range-invisible found beg-found)
-                                  (isearch-range-invisible beg-found found))))
-                 (if (if backward
-                          (re-search-backward regexp nil t)
-                        (re-search-forward regexp nil t))
-                     (setq found (point) beg-found (if backward (match-end 0)
-                                                      (match-beginning 0)))
-                   (setq give-up t)))
+                           (save-match-data
+                             (or (null found)
+                                 (if backward
+                                     (isearch-range-invisible found beg-found)
+                                   (isearch-range-invisible beg-found found))
+                                 ;; Skip node header line
+                                 (and (save-excursion (forward-line -1)
+                                                      (looking-at "\^_"))
+                                      (forward-line 1))
+                                 ;; Skip Tag Table node
+                                 (save-excursion
+                                   (and (search-backward "\^_" nil t)
+                                        (looking-at "\^_\nTag Table"))))))
+                 (let ((search-spaces-regexp Info-search-whitespace-regexp))
+                   (if (if backward
+                           (re-search-backward regexp nil t)
+                         (re-search-forward regexp nil t))
+                       (setq found (point) beg-found (if backward (match-end 0)
+                                                       (match-beginning 0)))
+                     (setq give-up t))))
                (if give-up
                    (setq found nil))
                (if found
@@ -1979,7 +2011,7 @@ Because of ambiguities, this should be concatenated with something like
               (if (match-beginning 5)
                   (string-to-number (match-string 5))
                 (buffer-substring (match-beginning 0) (1- (match-beginning 1)))))
-;;; Comment out the next line to use names of cross-references:
+;;; Uncomment next line to use names of cross-references in non-index nodes:
 ;;;       (setq Info-point-loc
 ;;;             (buffer-substring (match-beginning 0) (1- (match-beginning 1))))
       )
@@ -2802,8 +2834,7 @@ if point is in a menu item description, follow that menu item."
   "Follow a node reference near point.  Return non-nil if successful."
   (let (node)
     (cond
-     ((and (Info-get-token (point) "[hf]t?tp://" "[hf]t?tp://\\([^ \t\n\"`({<>})']+\\)")
-           (or (featurep 'browse-url) (require 'browse-url nil t)))
+     ((Info-get-token (point) "[hf]t?tp://" "[hf]t?tp://\\([^ \t\n\"`({<>})']+\\)")
       (setq node t)
       (browse-url (browse-url-url-at-point)))
      ((setq node (Info-get-token (point) "\\*note[ \n\t]+"
@@ -3213,7 +3244,7 @@ Allowed only if variable `Info-enable-edit' is non-nil."
        (message "Tags may have changed.  Use Info-tagify if necessary")))
 \f
 (defvar Info-file-list-for-emacs
-  '("ediff" "eudc" "forms" "gnus" "info" ("mh" . "mh-e")
+  '("ediff" "eudc" "forms" "gnus" "info" ("Info" . "info") ("mh" . "mh-e")
     "sc" "message" ("dired" . "dired-x") "viper" "vip" "idlwave"
     ("c" . "ccmode") ("c++" . "ccmode") ("objc" . "ccmode")
     ("java" . "ccmode") ("idl" . "ccmode") ("pike" . "ccmode")
@@ -3244,10 +3275,13 @@ The `info-file' property of COMMAND says which Info manual to search.
 If COMMAND has no property, the variable `Info-file-list-for-emacs'
 defines heuristics for which Info manual to try.
 The locations are of the format used in `Info-history', i.e.
-\(FILENAME NODENAME BUFFERPOS\)."
-  (let ((where '())
+\(FILENAME NODENAME BUFFERPOS\), where BUFFERPOS is the line number
+in the first element of the returned list (which is treated specially in
+`Info-goto-emacs-command-node'), and 0 for the rest elements of a list."
+  (let ((where '()) line-number
        (cmd-desc (concat "^\\* +" (regexp-quote (symbol-name command))
-                         "\\( <[0-9]+>\\)?:\\s *\\(.*\\)\\.$"))
+                         "\\( <[0-9]+>\\)?:\\s *\\(.*\\)\\."
+                         "\\(?:[ \t\n]+(line +\\([0-9]+\\))\\)?"))
        (info-file "emacs"))            ;default
     ;; Determine which info file this command is documented in.
     (if (get command 'info-file)
@@ -3261,6 +3295,7 @@ The locations are of the format used in `Info-history', i.e.
                           (car elt)
                         elt))
                 (file (if (consp elt) (cdr elt) elt))
+                (case-fold-search nil)
                 (regexp (concat "\\`" (regexp-quote name)
                                 "\\(\\'\\|-\\)")))
            (if (string-match regexp (symbol-name command))
@@ -3285,11 +3320,17 @@ The locations are of the format used in `Info-history', i.e.
                    (cons (list Info-current-file
                                (match-string-no-properties 2)
                                0)
-                         where)))
+                         where))
+             (setq line-number (and (match-beginning 3)
+                                    (string-to-number (match-string 3)))))
            (and (setq nodes (cdr nodes) node (car nodes))))
        (Info-goto-node node)))
-    where))
+    (if (and line-number where)
+       (cons (list (nth 0 (car where)) (nth 1 (car where)) line-number)
+             (cdr where))
+      where)))
 
+;;;###autoload (put 'Info-goto-emacs-command-node 'info-file "emacs")
 ;;;###autoload
 (defun Info-goto-emacs-command-node (command)
   "Go to the Info node in the Emacs manual for command COMMAND.
@@ -3313,9 +3354,11 @@ COMMAND must be a symbol or string."
          ;; Bind Info-history to nil, to prevent the last Index node
          ;; visited by Info-find-emacs-command-nodes from being
          ;; pushed onto the history.
-         (let ((Info-history nil) (Info-history-list nil))
-           (Info-find-node (car (car where))
-                           (car (cdr (car where)))))
+         (let ((Info-history nil) (Info-history-list nil)
+               (line-number (nth 2 (car where))))
+           (Info-find-node (nth 0 (car where)) (nth 1 (car where)))
+           (if (and (integerp line-number) (> line-number 0))
+               (forward-line (1- line-number))))
          (if (> num-matches 1)
              (progn
                ;; (car where) will be pushed onto Info-history
@@ -3329,6 +3372,7 @@ COMMAND must be a symbol or string."
                         (if (> num-matches 2) "them" "it")))))
       (error "Couldn't find documentation for %s" command))))
 
+;;;###autoload (put 'Info-goto-emacs-key-command-node 'info-file "emacs")
 ;;;###autoload
 (defun Info-goto-emacs-key-command-node (key)
   "Go to the node in the Emacs manual which describes the command bound to KEY.
@@ -3443,7 +3487,8 @@ Preserve text properties."
            (fontify-visited-p ; visited nodes need to be re-fontified
             (and Info-fontify-visited-nodes
                  ;; Don't take time to refontify visited nodes in huge nodes
-                 (< (- (point-max) (point-min)) Info-fontify-maximum-menu-size))))
+                 (< (- (point-max) (point-min)) Info-fontify-maximum-menu-size)))
+           rbeg rend)
 
       ;; Fontify header line
       (goto-char (point-min))
@@ -3568,39 +3613,48 @@ Preserve text properties."
                              "mouse-2: go to this node")
                 'mouse-face 'highlight)))
             (when (or not-fontified-p fontify-visited-p)
-              (add-text-properties
-               (match-beginning 2) (match-end 2)
-               (list
-                'font-lock-face
-                ;; Display visited nodes in a different face
-                (if (and Info-fontify-visited-nodes
-                         (save-match-data
-                           (let* ((node (replace-regexp-in-string
-                                         "^[ \t]+" ""
-                                         (replace-regexp-in-string
-                                          "[ \t\n]+" " "
-                                          (or (match-string 5)
-                                              (and (not (equal (match-string 4) ""))
-                                                   (match-string 4))
-                                              (match-string 2)))))
-                                  (file (file-name-nondirectory
-                                         Info-current-file))
-                                  (hl Info-history-list)
-                                  res)
-                             (if (string-match "(\\([^)]+\\))\\([^)]*\\)" node)
-                                 (setq file (file-name-nondirectory
-                                             (match-string 1 node))
-                                       node (if (equal (match-string 2 node) "")
-                                                "Top"
-                                              (match-string 2 node))))
-                             (while hl
-                               (if (and (string-equal node (nth 1 (car hl)))
-                                        (string-equal file
-                                                      (file-name-nondirectory
-                                                       (nth 0 (car hl)))))
-                                   (setq res (car hl) hl nil)
-                                 (setq hl (cdr hl))))
-                             res))) 'info-xref-visited 'info-xref))))
+              (setq rbeg (match-beginning 2)
+                    rend (match-end 2))
+              (put-text-property
+               rbeg rend
+               'font-lock-face
+               ;; Display visited nodes in a different face
+               (if (and Info-fontify-visited-nodes
+                        (save-match-data
+                          (let* ((node (replace-regexp-in-string
+                                        "^[ \t]+" ""
+                                        (replace-regexp-in-string
+                                         "[ \t\n]+" " "
+                                         (or (match-string 5)
+                                             (and (not (equal (match-string 4) ""))
+                                                  (match-string 4))
+                                             (match-string 2)))))
+                                 (file (file-name-nondirectory
+                                        Info-current-file))
+                                 (hl Info-history-list)
+                                 res)
+                            (if (string-match "(\\([^)]+\\))\\([^)]*\\)" node)
+                                (setq file (file-name-nondirectory
+                                            (match-string 1 node))
+                                      node (if (equal (match-string 2 node) "")
+                                               "Top"
+                                             (match-string 2 node))))
+                            (while hl
+                              (if (and (string-equal node (nth 1 (car hl)))
+                                       (string-equal file
+                                                     (file-name-nondirectory
+                                                      (nth 0 (car hl)))))
+                                  (setq res (car hl) hl nil)
+                                (setq hl (cdr hl))))
+                            res))) 'info-xref-visited 'info-xref))
+              ;; For multiline ref, unfontify newline and surrounding whitespace
+              (save-excursion
+                (goto-char rbeg)
+                (save-match-data
+                  (while (re-search-forward "\\s-*\n\\s-*" rend t nil)
+                    (remove-text-properties (match-beginning 0)
+                                            (match-end 0)
+                                            '(font-lock-face t))))))
             (when not-fontified-p
               (when (memq Info-hide-note-references '(t hide))
                 (add-text-properties (match-beginning 3) (match-end 3)