]> code.delx.au - gnu-emacs/blobdiff - lisp/info.el
(hif-nexttoken): Move to before first def.
[gnu-emacs] / lisp / info.el
index c5792482b7947d4e11fca82e5ec18fe28b60da65..660af03c959fbf57c35c7e9111b4b2317044d32a 100644 (file)
@@ -609,7 +609,7 @@ a case-insensitive match is tried."
               (erase-buffer)
               (if (eq filename t)
                   (Info-insert-dir)
-                (info-insert-file-contents filename t)
+                (info-insert-file-contents filename nil)
                 (setq default-directory (file-name-directory filename)))
               (set-buffer-modified-p nil)
               ;; See whether file has a tag table.  Record the location if yes.
@@ -1393,12 +1393,7 @@ FOOTNOTENAME may be an abbreviation of the reference name."
              (buffer-substring-no-properties beg (1- (point)))
            (skip-chars-forward " \t\n")
            (Info-following-node-name (if multi-line "^.,\t" "^.,\t\n"))))
-    (while (setq i (string-match "\n" str i))
-      (aset str i ?\ ))
-    ;; Collapse multiple spaces.
-    (while (string-match "  +" str)
-      (setq str (replace-match " " t t str)))
-    str))
+    (replace-regexp-in-string "[ \n]+" " " str)))
 
 ;; No one calls this.
 ;;(defun Info-menu-item-sequence (list)
@@ -1407,49 +1402,56 @@ FOOTNOTENAME may be an abbreviation of the reference name."
 ;;    (setq list (cdr list))))
 
 (defvar Info-complete-menu-buffer)
+(defvar Info-complete-next-re nil)
+(defvar Info-complete-cache nil)
 
 (defun Info-complete-menu-item (string predicate action)
-  (let ((completion-ignore-case t)
-       (case-fold-search t))
-    (cond ((eq action nil)
-          (let (completions
-                (pattern (concat "\n\\* +\\("
-                                 (regexp-quote string)
-                                 "[^:\t\n]*\\):")))
-            (save-excursion
-              (set-buffer Info-complete-menu-buffer)
-              (goto-char (point-min))
-              (search-forward "\n* Menu:")
-              (while (re-search-forward pattern nil t)
-                (setq completions
-                      (cons (cons (match-string-no-properties 1)
-                                  (match-beginning 1))
-                            completions))))
-            (try-completion string completions predicate)))
-         ((eq action t)
-          (let (completions
-                (pattern (concat "\n\\* +\\("
-                                 (regexp-quote string)
-                                 "[^:\t\n]*\\):")))
-            (save-excursion
-              (set-buffer Info-complete-menu-buffer)
-              (goto-char (point-min))
-              (search-forward "\n* Menu:")
-              (while (re-search-forward pattern nil t)
-                (setq completions (cons (cons
-                                         (match-string-no-properties 1)
-                                         (match-beginning 1))
-                                        completions))))
-            (all-completions string completions predicate)))
-         (t
-          (save-excursion
-            (set-buffer Info-complete-menu-buffer)
-            (goto-char (point-min))
-            (search-forward "\n* Menu:")
-            (re-search-forward (concat "\n\\* +"
-                                       (regexp-quote string)
-                                       ":")
-                               nil t))))))
+  (save-excursion
+    (set-buffer Info-complete-menu-buffer)
+    (let ((completion-ignore-case t)
+         (case-fold-search t)
+         (orignode Info-current-node)
+         nextnode)
+      (goto-char (point-min))
+      (search-forward "\n* Menu:")
+      (if (not (memq action '(nil t)))
+         (re-search-forward
+          (concat "\n\\* +" (regexp-quote string) ":") nil t)
+       (let ((pattern (concat "\n\\* +\\("
+                              (regexp-quote string)
+                              "[^:\t\n]*\\):"))
+             completions)
+         ;; Check the cache.
+         (if (and (equal (nth 0 Info-complete-cache) Info-current-file)
+                  (equal (nth 1 Info-complete-cache) Info-current-node)
+                  (equal (nth 2 Info-complete-cache) Info-complete-next-re)
+                  (let ((prev (nth 3 Info-complete-cache)))
+                    (eq t (compare-strings string 0 (length prev)
+                                           prev 0 nil t))))
+             ;; We can reuse the previous list.
+             (setq completions (nth 4 Info-complete-cache))
+           ;; The cache can't be used.
+           (while
+               (progn
+                 (while (re-search-forward pattern nil t)
+                   (push (cons (match-string-no-properties 1)
+                               (match-beginning 1))
+                         completions))
+                 ;; Check subsequent nodes if applicable.
+                 (and Info-complete-next-re
+                      (setq nextnode (Info-extract-pointer "next" t))
+                      (string-match Info-complete-next-re nextnode)))
+             (Info-goto-node nextnode))
+           ;; Go back to the start node (for the next completion).
+           (unless (equal Info-current-node orignode)
+             (Info-goto-node orignode))
+           ;; Update the cache.
+           (setq Info-complete-cache
+                 (list Info-current-file Info-current-node
+                       Info-complete-next-re string completions)))
+         (if action
+             (all-completions string completions predicate)
+           (try-completion string completions predicate)))))))
 
 
 (defun Info-menu (menu-item &optional fork)
@@ -1817,38 +1819,49 @@ parent node."
            (error "No cross references in this node")
          (Info-prev-reference t)))))
 
+(defun Info-goto-index ()
+  (Info-goto-node "Top")
+  (or (search-forward "\n* menu:" nil t)
+      (error "No index"))
+  (or (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t)
+      (error "No index"))
+  (goto-char (match-beginning 1))
+  ;; Protect Info-history so that the current node (Top) is not added to it.
+  (let ((Info-history nil))
+    (Info-goto-node (Info-extract-menu-node-name))))
+
 (defun Info-index (topic)
   "Look up a string TOPIC in the index for this file.
-The index is defined as the first node in the top-level menu whose
+The index is defined as the first node in the top level menu whose
 name contains the word \"Index\", plus any immediately following
 nodes whose names also contain the word \"Index\".
 If there are no exact matches to the specified topic, this chooses
 the first match which is a case-insensitive substring of a topic.
 Use the `,' command to see the other matches.
 Give a blank topic name to go to the Index node itself."
-  (interactive "sIndex topic: ")
+  (interactive
+   (list
+    (let ((Info-complete-menu-buffer (clone-buffer))
+         (Info-complete-next-re "\\<Index\\>"))
+      (unwind-protect
+         (with-current-buffer Info-complete-menu-buffer
+           (Info-goto-index)
+           (completing-read "Index topic: " 'Info-complete-menu-item))
+       (kill-buffer Info-complete-menu-buffer)))))
   (let ((orignode Info-current-node)
        (rnode nil)
        (pattern (format "\n\\* +\\([^\n:]*%s[^\n:]*\\):[ \t]*\\([^.\n]*\\)\\.[ \t]*\\([0-9]*\\)"
                         (regexp-quote topic)))
        node
        (case-fold-search t))
-    (Info-goto-node "Top")
-    (or (search-forward "\n* menu:" nil t)
-       (error "No index"))
-    (or (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t)
-       (error "No index"))
-    (goto-char (match-beginning 1))
-    ;; Here, and subsequently in this function,
-    ;; we bind Info-history to nil for internal node-switches
-    ;; so that we don't put junk in the history.
-    ;; In the first Info-goto-node call, above, we do update the history
-    ;; because that is what the user's previous node choice into it.
-    (let ((Info-history nil))
-      (Info-goto-node (Info-extract-menu-node-name)))
+    (Info-goto-index)
     (or (equal topic "")
        (let ((matches nil)
              (exact nil)
+             ;; We bind Info-history to nil for internal node-switches so
+             ;; that we don't put junk in the history.  In the first
+             ;; Info-goto-index call, above, we do update the history
+             ;; because that is what the user's previous node choice into it.
              (Info-history nil)
              found)
          (while
@@ -2156,8 +2169,7 @@ If no reference to follow, moves to the next node, or up if none."
        ;; Update menu menu.
        (let* ((Info-complete-menu-buffer (current-buffer))
               (items (nreverse (condition-case nil
-                                   (Info-complete-menu-item
-                                    "" (lambda (e) t) t)
+                                   (Info-complete-menu-item "" nil t)
                                  (error nil))))
               entries current
               (number 0))
@@ -2230,6 +2242,7 @@ The name of the info file is prepended to the node name in parentheses."
 \f
 ;; Info mode is suitable only for specially formatted data.
 (put 'Info-mode 'mode-class 'special)
+(put 'Info-mode 'no-clone-indirect t)
 
 (defun Info-mode ()
   "Info mode provides commands for browsing through the Info documentation tree.
@@ -2382,7 +2395,8 @@ Allowed only if variable `Info-enable-edit' is non-nil."
     ("copyright" . "autotype") ("executable" . "autotype")
     ("time-stamp" . "autotype") ("quickurl" . "autotype")
     ("tempo" . "autotype") ("hippie-expand" . "autotype")
-    ("cvs" . "pcl-cvs") ("ada" . "ada-mode")
+    ("cvs" . "pcl-cvs") ("ada" . "ada-mode") "calc"
+    ("calcAlg" . "calc") ("calcDigit" . "calc") ("calcVar" . "calc")
     "ebrowse" "eshell" "cl" "reftex" "speedbar" "widget" "woman"
     ("mail-header" . "emacs-mime") ("mail-content" . "emacs-mime")
     ("mail-encode" . "emacs-mime") ("mail-decode" . "emacs-mime")
@@ -2583,8 +2597,8 @@ the variable `Info-file-list-for-emacs'."
                                             ("Up" . Info-up))))))
                  (when fun
                    (let ((keymap (make-sparse-keymap)))
-                     (define-key keymap [header-line mouse-1] fun)
-                     (define-key keymap [header-line mouse-2] fun)
+                     (define-key keymap [header-line down-mouse-1] fun)
+                     (define-key keymap [header-line down-mouse-2] fun)
                      (put-text-property tbeg nend 'local-map keymap))))
                ))))
        (goto-char (point-min))
@@ -2622,7 +2636,7 @@ the variable `Info-file-list-for-emacs'."
            (let ((n 0))
              (while (re-search-forward "^\\* +\\([^:\t\n]*\\):" nil t)
                (setq n (1+ n))
-               (if (memq n '(5 9))     ; visual aids to help with 1-9 keys
+               (if (zerop (% n 3)) ; visual aids to help with 1-9 keys
                    (put-text-property (match-beginning 0)
                                       (1+ (match-beginning 0))
                                       'face 'info-menu-5))