]> code.delx.au - gnu-emacs/blobdiff - lisp/info.el
* NEWS: Add paragraphs for CEDET and EIEIO.
[gnu-emacs] / lisp / info.el
index 0afb3f01339012d49986e7d7d42cedba046a4605..96c22e151106134044c03a03e6bf224d3e626c46 100644 (file)
@@ -1,6 +1,6 @@
 ;; info.el --- info package for Emacs
 
-;; Copyright (C) 1985-1986, 1992-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1985-1986, 1992-2013 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: help
@@ -32,8 +32,6 @@
 
 ;;; Code:
 
-(eval-when-compile (require 'cl))
-
 (defgroup info nil
   "Info subsystem."
   :group 'help
@@ -344,12 +342,12 @@ a tab, a carriage return (control-M), a newline, and `]+'."
 (defcustom Info-isearch-search t
   "If non-nil, isearch in Info searches through multiple nodes.
 Before leaving the initial Info node, where isearch was started,
-it fails once with the error message [initial node], and with
+it fails once with the error message [end of node], and with
 subsequent C-s/C-r continues through other nodes without failing
 with this error message in other nodes.  When isearch fails for
-the rest of the manual, it wraps around the whole manual and
-restarts the search from the top/final node depending on
-search direction.
+the rest of the manual, it displays the error message [end of manual],
+wraps around the whole manual and restarts the search from the top/final
+node depending on search direction.
 
 Setting this option to nil restores the default isearch behavior
 with wrapping around the current Info node."
@@ -419,6 +417,21 @@ If number, the point is moved to the corresponding line.")
 (defvar Info-standalone nil
   "Non-nil if Emacs was started solely as an Info browser.")
 
+(defvar Info-file-attributes nil
+  "Alist of file attributes of visited Info files.
+Each element is a list (FILE-NAME FILE-ATTRIBUTES...).")
+
+(defvar Info-toc-nodes nil
+  "Alist of cached parent-children node information in visited Info files.
+Each element is (FILE (NODE-NAME PARENT SECTION CHILDREN) ...)
+where PARENT is the parent node extracted from the Up pointer,
+SECTION is the section name in the Top node where this node is placed,
+CHILDREN is a list of child nodes extracted from the node menu.")
+
+(defvar Info-index-nodes nil
+  "Alist of cached index node names of visited Info files.
+Each element has the form (INFO-FILE INDEX-NODE-NAMES-LIST).")
+
 (defvar Info-virtual-files nil
   "List of definitions of virtual Info files.
 Each element of the list has the format (FILENAME (OPERATION . HANDLER) ...)
@@ -611,7 +624,26 @@ Do the right thing if the file has been compressed or zipped."
            (apply 'call-process-region (point-min) (point-max)
                   (car decoder) t t nil (cdr decoder))))
       (let ((inhibit-null-byte-detection t)) ; Index nodes include null bytes
-       (insert-file-contents fullname visit)))))
+       (insert-file-contents fullname visit)))
+
+    ;; Clear the caches of modified Info files.
+    (let* ((attribs-old (cdr (assoc fullname Info-file-attributes)))
+          (modtime-old (and attribs-old (nth 5 attribs-old)))
+          (attribs-new (and (stringp fullname) (file-attributes fullname)))
+          (modtime-new (and attribs-new (nth 5 attribs-new))))
+      (when (and modtime-old modtime-new
+                (> (float-time modtime-new) (float-time modtime-old)))
+       (setq Info-index-nodes (remove (assoc (or Info-current-file filename)
+                                             Info-index-nodes)
+                                      Info-index-nodes))
+       (setq Info-toc-nodes (remove (assoc (or Info-current-file filename)
+                                           Info-toc-nodes)
+                                    Info-toc-nodes)))
+      ;; Add new modtime to `Info-file-attributes'.
+      (setq Info-file-attributes
+           (cons (cons fullname attribs-new)
+                 (remove (assoc fullname Info-file-attributes)
+                         Info-file-attributes))))))
 
 (defun Info-file-supports-index-cookies (&optional file)
   "Return non-nil value if FILE supports Info index cookies.
@@ -1850,9 +1882,7 @@ If DIRECTION is `backward', search in the reverse direction."
          (while (and (not give-up)
                      (or (null found)
                          (not (funcall isearch-filter-predicate beg-found found))))
-           (let ((search-spaces-regexp
-                  (if (or (not isearch-mode) isearch-regexp)
-                      Info-search-whitespace-regexp)))
+           (let ((search-spaces-regexp Info-search-whitespace-regexp))
              (if (if backward
                      (re-search-backward regexp bound t)
                    (re-search-forward regexp bound t))
@@ -1865,16 +1895,14 @@ If DIRECTION is `backward', search in the reverse direction."
                 (not bound)
                 (or give-up (and found (not (and (> found opoint-min)
                                                  (< found opoint-max))))))
-       (signal 'search-failed (list regexp "initial node")))
+       (signal 'search-failed (list regexp "end of node")))
 
       ;; If no subfiles, give error now.
       (if give-up
          (if (null Info-current-subfile)
              (if isearch-mode
                  (signal 'search-failed (list regexp "end of manual"))
-               (let ((search-spaces-regexp
-                      (if (or (not isearch-mode) isearch-regexp)
-                          Info-search-whitespace-regexp)))
+               (let ((search-spaces-regexp Info-search-whitespace-regexp))
                  (if backward
                      (re-search-backward regexp)
                    (re-search-forward regexp))))
@@ -1932,9 +1960,7 @@ If DIRECTION is `backward', search in the reverse direction."
                (while (and (not give-up)
                            (or (null found)
                                (not (funcall isearch-filter-predicate beg-found found))))
-                 (let ((search-spaces-regexp
-                        (if (or (not isearch-mode) isearch-regexp)
-                            Info-search-whitespace-regexp)))
+                 (let ((search-spaces-regexp Info-search-whitespace-regexp))
                    (if (if backward
                            (re-search-backward regexp nil t)
                          (re-search-forward regexp nil t))
@@ -2002,21 +2028,26 @@ If DIRECTION is `backward', search in the reverse direction."
 (defun Info-isearch-search ()
   (if Info-isearch-search
       (lambda (string &optional bound noerror count)
-       (Info-search
-        (cond
-         (isearch-word
-          ;; Lax version of word search
-          (let ((lax (not (or isearch-nonincremental
-                              (eq (length string)
-                                  (length (isearch-string-state
-                                           (car isearch-cmds))))))))
-            (if (functionp isearch-word)
-                (funcall isearch-word string lax)
-              (word-search-regexp string lax))))
-         (isearch-regexp string)
-         (t (regexp-quote string)))
-        bound noerror count
-        (unless isearch-forward 'backward))
+       (let ((Info-search-whitespace-regexp
+              (if (if isearch-regexp
+                      isearch-regexp-lax-whitespace
+                    isearch-lax-whitespace)
+                  search-whitespace-regexp)))
+         (Info-search
+          (cond
+           (isearch-word
+            ;; Lax version of word search
+            (let ((lax (not (or isearch-nonincremental
+                                (eq (length string)
+                                    (length (isearch--state-string
+                                             (car isearch-cmds))))))))
+              (if (functionp isearch-word)
+                  (funcall isearch-word string lax)
+                (word-search-regexp string lax))))
+           (isearch-regexp string)
+           (t (regexp-quote string)))
+          bound noerror count
+          (unless isearch-forward 'backward)))
        (point))
     (isearch-search-fun-default)))
 
@@ -2396,13 +2427,6 @@ Table of contents is created from the tree structure of menus."
       (message "")
       (nreverse nodes))))
 
-(defvar Info-toc-nodes nil
-  "Alist of cached parent-children node information in visited Info files.
-Each element is (FILE (NODE-NAME PARENT SECTION CHILDREN) ...)
-where PARENT is the parent node extracted from the Up pointer,
-SECTION is the section name in the Top node where this node is placed,
-CHILDREN is a list of child nodes extracted from the node menu.")
-
 (defun Info-toc-nodes (filename)
   "Return a node list of Info FILENAME with parent-children information.
 This information is cached in the variable `Info-toc-nodes' with the help
@@ -2622,6 +2646,7 @@ Because of ambiguities, this should be concatenated with something like
                     (while (re-search-forward pattern nil t)
                       (push (match-string-no-properties 1)
                             completions))
+                   (setq completions (delete-dups completions))
                     ;; Check subsequent nodes if applicable.
                     (or (and Info-complete-next-re
                              (setq nextnode (Info-extract-pointer "next" t))
@@ -2856,7 +2881,7 @@ N is the digit argument used to invoke this command."
                      (Info-extract-menu-node-name)))))
 
 (defmacro Info-no-error (&rest body)
-  (list 'condition-case nil (cons 'progn (append body '(t))) '(error nil)))
+  `(condition-case nil (progn ,@body t) (error nil)))
 
 (defun Info-next-preorder ()
   "Go to the next subnode or the next node, or go up a level."
@@ -3034,10 +3059,6 @@ See `Info-scroll-down'."
       (if (looking-at "^\\* ")
          (forward-char 2)))))
 \f
-(defvar Info-index-nodes nil
-  "Alist of cached index node names of visited Info files.
-Each element has the form (INFO-FILE INDEX-NODE-NAMES-LIST).")
-
 (defun Info-index-nodes (&optional file)
   "Return a list of names of all index nodes in Info FILE.
 If FILE is omitted, it defaults to the current Info file.
@@ -4136,8 +4157,6 @@ Advanced commands:
        'Info-isearch-push-state)
   (set (make-local-variable 'isearch-filter-predicate)
        'Info-isearch-filter)
-  (set (make-local-variable 'search-whitespace-regexp)
-       Info-search-whitespace-regexp)
   (set (make-local-variable 'revert-buffer-function)
        'Info-revert-buffer-function)
   (Info-set-mode-line)
@@ -4506,7 +4525,17 @@ first line or header line, and for breadcrumb links.")
              ((not (bobp))
               ;; Hide the punctuation at the end, too.
               (skip-chars-backward " \t,")
-              (put-text-property (point) header-end 'invisible t))))))
+              (put-text-property (point) header-end 'invisible t)
+             ;; Hide the suffix of the Info file name.
+             (beginning-of-line)
+             (if (re-search-forward
+                  (format "File: %s\\([^,\n\t]+\\),"
+                          (if (stringp Info-current-file)
+                              (file-name-nondirectory Info-current-file)
+                            Info-current-file))
+                  header-end t)
+                 (put-text-property (match-beginning 1) (match-end 1)
+                                    'invisible t)))))))
 
       ;; Fontify titles
       (goto-char (point-min))
@@ -4794,6 +4823,12 @@ first line or header line, and for breadcrumb links.")
                                  mouse-face highlight
                                  help-echo "mouse-2: go to this URL"))))
 
+      ;; Hide empty lines at the end of the node.
+      (goto-char (point-max))
+      (skip-chars-backward "\n")
+      (when (< (point) (1- (point-max)))
+       (put-text-property (point) (1- (point-max)) 'invisible t))
+
       (set-buffer-modified-p nil))))
 \f
 ;;; Speedbar support:
@@ -5022,11 +5057,18 @@ BUFFER is the buffer speedbar is requesting buttons for."
 (defun Info-bookmark-make-record ()
   "This implements the `bookmark-make-record-function' type (which see)
 for Info nodes."
-  `(,Info-current-node
-    ,@(bookmark-make-record-default 'no-file)
-    (filename . ,Info-current-file)
-    (info-node . ,Info-current-node)
-    (handler . Info-bookmark-jump)))
+  (let* ((file (and (stringp Info-current-file)
+                   (file-name-nondirectory Info-current-file)))
+        (bookmark-name (if file
+                           (concat "(" file ") " Info-current-node)
+                         Info-current-node))
+        (defaults (delq nil (list bookmark-name file Info-current-node))))
+    `(,bookmark-name
+      ,@(bookmark-make-record-default 'no-file)
+      (filename . ,Info-current-file)
+      (info-node . ,Info-current-node)
+      (handler . Info-bookmark-jump)
+      (defaults . ,defaults))))
 
 ;;;###autoload
 (defun Info-bookmark-jump (bmk)