]> code.delx.au - gnu-emacs/blobdiff - lisp/info.el
(command-line-1): Refer to "Pure Storage" on
[gnu-emacs] / lisp / info.el
index cbb8ec57e315fd1b4ff124142fad9bb61fb8e6b6..163441893dbf798c238f4d50453fbc3f2274eb64 100644 (file)
@@ -1,7 +1,7 @@
 ;;; info.el --- info package for Emacs
 
 ;; Copyright (C) 1985, 1986, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;;   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+;;   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: help
@@ -129,21 +129,14 @@ The Lisp code is executed when the node is selected.")
 (put 'info-menu-5 'face-alias 'info-menu-star)
 
 (defface info-xref
-  '((((min-colors 88)
-      (class color) (background light)) :foreground "blue1" :underline t)
-    (((class color) (background light)) :foreground "blue" :underline t)
-    (((min-colors 88)
-      (class color) (background dark)) :foreground "cyan1" :underline t)
-    (((class color) (background dark)) :foreground "cyan" :underline t)
-    (t :underline t))
-  "Face for Info cross-references."
+  '((t :inherit link))
+  "Face for unvisited Info cross-references."
   :group 'info)
 
 (defface info-xref-visited
-  '((default :inherit info-xref)
-    (((class color) (background light)) :foreground "magenta4")
-    (((class color) (background dark)) :foreground "violet"))
+  '((t :inherit (link-visited info-xref)))
   "Face for visited Info cross-references."
+  :version "22.1"
   :group 'info)
 
 (defcustom Info-fontify-visited-nodes t
@@ -290,8 +283,7 @@ with wrapping around the current Info node."
 (defvar Info-current-file nil
   "Info file that Info is now looking at, or nil.
 This is the name that was specified in Info, not the actual file name.
-It doesn't contain directory names or file name extensions added by Info.
-Can also be t when using `Info-on-current-buffer'.")
+It doesn't contain directory names or file name extensions added by Info.")
 
 (defvar Info-current-subfile nil
   "Info subfile that is actually in the *info* buffer now.
@@ -449,8 +441,7 @@ Do the right thing if the file has been compressed or zipped."
       (or tail
          (error "Can't find %s or any compressed version of it" filename)))
     ;; check for conflict with jka-compr
-    (if (and (featurep 'jka-compr)
-            (jka-compr-installed-p)
+    (if (and (jka-compr-installed-p)
             (jka-compr-get-compression-info fullname))
        (setq decoder nil))
     (if decoder
@@ -523,22 +514,22 @@ Do the right thing if the file has been compressed or zipped."
               (Info-default-dirs)))))))
 
 ;;;###autoload
-(defun info-other-window (&optional file)
+(defun info-other-window (&optional file-or-node)
   "Like `info' but show the Info buffer in another window."
   (interactive (if current-prefix-arg
                   (list (read-file-name "Info file name: " nil nil t))))
   (let (same-window-buffer-names same-window-regexps)
-    (info file)))
+    (info file-or-node)))
 
 ;;;###autoload (add-hook 'same-window-regexps "\\*info\\*\\(\\|<[0-9]+>\\)")
 
 ;;;###autoload (put 'info 'info-file "emacs")
 ;;;###autoload
-(defun info (&optional file buffer)
+(defun info (&optional file-or-node buffer)
   "Enter Info, the documentation browser.
-Optional argument FILE specifies the file to examine;
+Optional argument FILE-OR-NODE specifies the file to examine;
 the default is the top-level directory of Info.
-Called from a program, FILE may specify an Info node of the form
+Called from a program, FILE-OR-NODE may specify an Info node of the form
 `(FILENAME)NODENAME'.
 Optional argument BUFFER specifies the Info buffer name;
 the default buffer name is *info*.  If BUFFER exists,
@@ -561,17 +552,19 @@ in all the directories in that path."
   (pop-to-buffer (or buffer "*info*"))
   (if (and buffer (not (eq major-mode 'Info-mode)))
       (Info-mode))
-  (if file
+  (if file-or-node
       ;; If argument already contains parentheses, don't add another set
       ;; since the argument will then be parsed improperly.  This also
       ;; has the added benefit of allowing node names to be included
       ;; following the parenthesized filename.
       (Info-goto-node
-       (if (and (stringp file) (string-match "(.*)" file))
-           file
-         (concat "(" file ")")))
-    (if (zerop (buffer-size))
-        (Info-directory))))
+       (if (and (stringp file-or-node) (string-match "(.*)" file-or-node))
+           file-or-node
+         (concat "(" file-or-node ")")))
+    (if (and (zerop (buffer-size))
+            (null Info-history))
+       ;; If we just created the Info buffer, go to the directory.
+       (Info-directory))))
 
 ;;;###autoload
 (defun info-emacs-manual ()
@@ -629,12 +622,6 @@ just return nil (no error)."
        (cond
         ((string= (downcase filename) "dir")
          (setq found t))
-        ((string= filename "apropos")
-         (setq found 'apropos))
-        ((string= filename "history")
-         (setq found 'history))
-        ((string= filename "toc")
-         (setq found 'toc))
         (t
          (let ((dirs (if (string-match "^\\./" filename)
                           ;; If specified name starts with `./'
@@ -680,7 +667,8 @@ just return nil (no error)."
           (if noerror
               (setq filename nil)
             (error "Info file %s does not exist" filename)))
-        filename)))
+        filename)
+    (and (member filename '(apropos history toc)) filename)))
 
 (defun Info-find-node (filename nodename &optional no-going-back)
   "Go to an Info node specified as separate FILENAME and NODENAME.
@@ -690,17 +678,19 @@ it says do not attempt further (recursive) error recovery."
   (setq filename (Info-find-file filename))
   ;; Go into Info buffer.
   (or (eq major-mode 'Info-mode) (pop-to-buffer "*info*"))
-  ;; Record the node we are leaving.
-  (if (and Info-current-file (not no-going-back))
-      (setq Info-history
-            (cons (list Info-current-file Info-current-node (point))
-                  Info-history)))
+  ;; Record the node we are leaving, if we were in one.
+  (and (not no-going-back)
+       Info-current-file
+       (setq Info-history
+            (cons (list Info-current-file Info-current-node (point))
+                  Info-history)))
   (Info-find-node-2 filename nodename no-going-back))
 
+;;;###autoload
 (defun Info-on-current-buffer (&optional nodename)
-  "Use the `Info-mode' to browse the current Info buffer.
-If a prefix arg is provided, it queries for the NODENAME which
-else defaults to \"Top\"."
+  "Use Info mode to browse the current Info buffer.
+With a prefix arg, this queries for the node name to visit first;
+otherwise, that defaults to `Top'."
   (interactive
    (list (if current-prefix-arg
             (completing-read "Node name: " (Info-build-node-completions)
@@ -708,7 +698,10 @@ else defaults to \"Top\"."
   (unless nodename (setq nodename "Top"))
   (info-initialize)
   (Info-mode)
-  (set (make-local-variable 'Info-current-file) t)
+  (set (make-local-variable 'Info-current-file)
+       (or buffer-file-name
+          ;; If called on a non-file buffer, make a fake file name.
+          (concat default-directory (buffer-name))))
   (Info-find-node-2 nil nodename))
 
 ;; It's perhaps a bit nasty to kill the *info* buffer to force a re-read,
@@ -726,8 +719,8 @@ is preserved, if possible."
        (pline        (count-lines (point-min) (line-beginning-position)))
        (wline        (count-lines (point-min) (window-start)))
        (old-history  Info-history)
-       (new-history (and Info-current-file
-                         (list Info-current-file Info-current-node (point)))))
+       (new-history  (and Info-current-file
+                          (list Info-current-file Info-current-node (point)))))
     (kill-buffer (current-buffer))
     (Info-find-node filename nodename)
     (setq Info-history old-history)
@@ -893,9 +886,6 @@ a case-insensitive match is tried."
               (setq Info-current-file
                    (cond
                     ((eq filename t) "dir")
-                    ((eq filename 'apropos) "apropos")
-                    ((eq filename 'history) "history")
-                    ((eq filename 'toc) "toc")
                     (t filename)))
              ))
         ;; Use string-equal, not equal, to ignore text props.
@@ -1206,7 +1196,9 @@ a case-insensitive match is tried."
                  (point)
                  (if (re-search-forward "^[^* \n\t]" nil t)
                      (match-beginning 0)
-                   (or limit (point-max)))) entries))))
+                   (or limit (point-max))))
+                entries)
+               (forward-line 0))))
          ;; Insert the entries just found.
          (while (= (line-beginning-position 0) (1- (point)))
            (backward-char))
@@ -1217,10 +1209,11 @@ a case-insensitive match is tried."
 
          ;; Now remove duplicate entries under the same heading.
          (let ((seen nil)
-               (limit (point)))
+               (limit (point-marker)))
            (goto-char start)
-           (while (re-search-forward "^* \\([^:\n]+:\\(:\\|[^.\n]+\\).\\)"
-                                     limit 'move)
+           (while (and (> limit (point))
+                       (re-search-forward "^* \\([^:\n]+:\\(:\\|[^.\n]+\\).\\)"
+                                          limit 'move))
              ;; Fold case straight away; `member-ignore-case' here wasteful.
              (let ((x (downcase (match-string 1))))
                (if (member x seen)
@@ -1395,17 +1388,33 @@ any double quotes or backslashes must be escaped (\\\",\\\\)."
        (Info-hide-cookies-node)
        (run-hooks 'Info-selection-hook)))))
 
+(defvar Info-mode-line-node-keymap
+  (let ((map (make-sparse-keymap)))
+    (define-key map [mode-line mouse-1] 'Info-scroll-up)
+    (define-key map [mode-line mouse-3] 'Info-scroll-down)
+    map)
+  "Keymap to put on the Info node name in the mode line.")
+
 (defun Info-set-mode-line ()
   (setq mode-line-buffer-identification
        (nconc (propertized-buffer-identification "%b")
               (list
-               (concat " ("
-                       (file-name-nondirectory
-                        (if (stringp Info-current-file)
-                            Info-current-file
-                          (or buffer-file-name "")))
-                       ") "
-                       (or Info-current-node ""))))))
+               (concat
+                " ("
+                (if (stringp Info-current-file)
+                    (replace-regexp-in-string
+                     "%" "%%" (file-name-nondirectory Info-current-file))
+                  (format "*%S*" Info-current-file))
+                ") "
+                (if Info-current-node
+                    (propertize (replace-regexp-in-string
+                                 "%" "%%" Info-current-node)
+                                'face 'mode-line-buffer-id
+                                'help-echo
+                                "mouse-1: scroll forward, mouse-3: scroll back"
+                                'mouse-face 'mode-line-highlight
+                                'local-map Info-mode-line-node-keymap)
+                  ""))))))
 \f
 ;; Go to an Info node specified with a filename-and-nodename string
 ;; of the sort that is found in pointers in nodes.
@@ -1518,7 +1527,12 @@ PATH-AND-SUFFIXES is a pair of lists, (DIRECTORIES . SUFFIXES)."
 
 ;; Arrange to highlight the proper letters in the completion list buffer.
 (put 'Info-read-node-name-1 'completion-base-size-function
-     (lambda () 1))
+     (lambda ()
+       (if (string-match "\\`([^)]*\\'"
+                        (or completion-common-substring
+                            (minibuffer-completion-contents)))
+          1
+        0)))
 
 (defun Info-read-node-name (prompt &optional default)
   (let* ((completion-ignore-case t)
@@ -1629,8 +1643,11 @@ If DIRECTION is `backward', search in the reverse direction."
                            ;; Skip Tag Table node
                            (save-excursion
                              (and (search-backward "\^_" nil t)
-                                  (looking-at "\^_\nTag Table"))))))
-           (let ((search-spaces-regexp Info-search-whitespace-regexp))
+                                  (looking-at
+                                   "\^_\n\\(Tag Table\\|Local Variables\\)"))))))
+           (let ((search-spaces-regexp
+                  (if (or (not isearch-mode) isearch-regexp)
+                      Info-search-whitespace-regexp)))
              (if (if backward
                      (re-search-backward regexp bound t)
                    (re-search-forward regexp bound t))
@@ -1648,7 +1665,9 @@ If DIRECTION is `backward', search in the reverse direction."
       ;; If no subfiles, give error now.
       (if give-up
          (if (null Info-current-subfile)
-             (let ((search-spaces-regexp Info-search-whitespace-regexp))
+             (let ((search-spaces-regexp
+                    (if (or (not isearch-mode) isearch-regexp)
+                        Info-search-whitespace-regexp)))
                (if backward
                    (re-search-backward regexp)
                  (re-search-forward regexp)))
@@ -1717,8 +1736,11 @@ If DIRECTION is `backward', search in the reverse direction."
                                  ;; Skip Tag Table node
                                  (save-excursion
                                    (and (search-backward "\^_" nil t)
-                                        (looking-at "\^_\nTag Table"))))))
-                 (let ((search-spaces-regexp Info-search-whitespace-regexp))
+                                        (looking-at
+                                         "\^_\n\\(Tag Table\\|Local Variables\\)"))))))
+                 (let ((search-spaces-regexp
+                        (if (or (not isearch-mode) isearch-regexp)
+                            Info-search-whitespace-regexp)))
                    (if (if backward
                            (re-search-backward regexp nil t)
                          (re-search-forward regexp nil t))
@@ -1812,11 +1834,11 @@ If DIRECTION is `backward', search in the reverse direction."
 
 (defun Info-isearch-push-state ()
   `(lambda (cmd)
-     (Info-isearch-pop-state cmd ,Info-current-file ,Info-current-node)))
+     (Info-isearch-pop-state cmd ',Info-current-file ',Info-current-node)))
 
 (defun Info-isearch-pop-state (cmd file node)
-  (or (and (string= Info-current-file file)
-           (string= Info-current-node node))
+  (or (and (equal Info-current-file file)
+           (equal Info-current-node node))
       (progn (Info-find-node file node) (sit-for 0))))
 
 (defun Info-isearch-start ()
@@ -1834,7 +1856,7 @@ if ERRORNAME is nil, just return nil."
        (forward-line 1)
        (cond ((re-search-backward
                (concat name ":" (Info-following-node-name-re)) bound t)
-              (match-string 1))
+              (match-string-no-properties 1))
              ((not (eq errorname t))
               (error "Node has no %s"
                      (capitalize (or errorname name)))))))))
@@ -1856,7 +1878,7 @@ End of submatch 0, 1, and 3 are the same, so you can safely concat."
 ;;; For compatibility; other files have used this name.
 (defun Info-following-node-name ()
   (and (looking-at (Info-following-node-name-re))
-       (match-string 1)))
+       (match-string-no-properties 1)))
 
 (defun Info-next ()
   "Go to the next node of this node."
@@ -1884,13 +1906,14 @@ If SAME-FILE is non-nil, do not move to a different Info file."
     (let ((old-node Info-current-node)
          (old-file Info-current-file)
          (node (Info-extract-pointer "up")) p)
-      (and (or same-file (not (stringp Info-current-file)))
+      (and same-file
           (string-match "^(" node)
           (error "Up node is in another Info file"))
       (Info-goto-node node)
       (setq p (point))
       (goto-char (point-min))
-      (if (and (search-forward "\n* Menu:" nil t)
+      (if (and (stringp old-file)
+              (search-forward "\n* Menu:" nil t)
               (re-search-forward
                (if (string-equal old-node "Top")
                    (concat "\n\\*[^:]+: +(" (file-name-nondirectory old-file) ")")
@@ -1958,51 +1981,53 @@ If SAME-FILE is non-nil, do not move to a different Info file."
           (while hl
             (let ((file (nth 0 (car hl)))
                   (node (nth 1 (car hl))))
-              (if (and (string-equal file curr-file)
-                       (string-equal node curr-node))
+              (if (and (equal file curr-file)
+                       (equal node curr-node))
                   (setq p (point)))
-              (insert "* " node ": ("
-                     (propertize (or (file-name-directory file) "") 'invisible t)
-                     (file-name-nondirectory file)
-                      ")" node ".\n"))
+              (if (stringp file)
+                 (insert "* " node ": ("
+                         (propertize (or (file-name-directory file) "") 'invisible t)
+                         (file-name-nondirectory file)
+                         ")" node ".\n")))
             (setq hl (cdr hl))))))
-    (Info-find-node "history" "Top")
+    (Info-find-node 'history "Top")
     (goto-char (or p (point-min)))))
 
 (defun Info-toc ()
   "Go to a node with table of contents of the current Info file.
 Table of contents is created from the tree structure of menus."
   (interactive)
-  (let ((curr-file (substring-no-properties Info-current-file))
-        (curr-node (substring-no-properties Info-current-node))
-        p)
-    (with-current-buffer (get-buffer-create " *info-toc*")
-      (let ((inhibit-read-only t)
-            (node-list (Info-build-toc curr-file)))
-        (erase-buffer)
-        (goto-char (point-min))
-        (insert "\n\^_\nFile: toc,  Node: Top,  Up: (dir)\n\n")
-        (insert "Table of Contents\n*****************\n\n")
-        (insert "*Note Top: (" curr-file ")Top.\n")
-        (Info-insert-toc
-         (nth 2 (assoc "Top" node-list)) ; get Top nodes
-         node-list 0 curr-file))
-      (if (not (bobp))
-          (let ((Info-hide-note-references 'hide)
-                (Info-fontify-visited-nodes nil))
-            (Info-mode)
-            (setq Info-current-file "toc" Info-current-node "Top")
-            (goto-char (point-min))
-            (narrow-to-region (or (re-search-forward "\n[\^_\f]\n" nil t)
-                                  (point-min))
-                              (point-max))
-            (Info-fontify-node)
-            (widen)))
-      (goto-char (point-min))
-      (if (setq p (search-forward (concat "*Note " curr-node ":") nil t))
-          (setq p (- p (length curr-node) 2))))
-    (Info-find-node "toc" "Top")
-    (goto-char (or p (point-min)))))
+  (if (stringp Info-current-file)
+      (let ((curr-file (substring-no-properties Info-current-file))
+           (curr-node (substring-no-properties Info-current-node))
+           p)
+       (with-current-buffer (get-buffer-create " *info-toc*")
+         (let ((inhibit-read-only t)
+               (node-list (Info-build-toc curr-file)))
+           (erase-buffer)
+           (goto-char (point-min))
+           (insert "\n\^_\nFile: toc,  Node: Top,  Up: (dir)\n\n")
+           (insert "Table of Contents\n*****************\n\n")
+           (insert "*Note Top: (" curr-file ")Top.\n")
+           (Info-insert-toc
+            (nth 2 (assoc "Top" node-list)) ; get Top nodes
+            node-list 0 curr-file))
+         (if (not (bobp))
+             (let ((Info-hide-note-references 'hide)
+                   (Info-fontify-visited-nodes nil))
+               (Info-mode)
+               (setq Info-current-file 'toc Info-current-node "Top")
+               (goto-char (point-min))
+               (narrow-to-region (or (re-search-forward "\n[\^_\f]\n" nil t)
+                                     (point-min))
+                                 (point-max))
+               (Info-fontify-node)
+               (widen)))
+         (goto-char (point-min))
+         (if (setq p (search-forward (concat "*Note " curr-node ":") nil t))
+             (setq p (- p (length curr-node) 2))))
+       (Info-find-node 'toc "Top")
+       (goto-char (or p (point-min))))))
 
 (defun Info-insert-toc (nodes node-list level curr-file)
   "Insert table of contents with references to nodes."
@@ -2202,16 +2227,18 @@ Because of ambiguities, this should be concatenated with something like
         (setq Info-point-loc
               (if (match-beginning 5)
                   (string-to-number (match-string 5))
-                (buffer-substring (match-beginning 0) (1- (match-beginning 1)))))
+                (buffer-substring-no-properties
+                (match-beginning 0) (1- (match-beginning 1)))))
 ;;; 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))))
       )
     (replace-regexp-in-string
      "[ \n]+" " "
-     (or (match-string 2)
+     (or (match-string-no-properties 2)
         ;; If the node name is the menu entry name (using `entry::').
-        (buffer-substring (match-beginning 0) (1- (match-beginning 1)))))))
+        (buffer-substring-no-properties
+         (match-beginning 0) (1- (match-beginning 1)))))))
 
 ;; No one calls this.
 ;;(defun Info-menu-item-sequence (list)
@@ -2256,7 +2283,8 @@ Because of ambiguities, this should be concatenated with something like
        (let ((pattern (concat "\n\\* +\\("
                               (regexp-quote string)
                               Info-menu-entry-name-re "\\):" Info-node-spec-re))
-             completions)
+             completions
+             (complete-nodes Info-complete-nodes))
          ;; Check the cache.
          (if (and (equal (nth 0 Info-complete-cache) Info-current-file)
                   (equal (nth 1 Info-complete-cache) Info-current-node)
@@ -2277,9 +2305,9 @@ Because of ambiguities, this should be concatenated with something like
                  (or (and Info-complete-next-re
                           (setq nextnode (Info-extract-pointer "next" t))
                           (string-match Info-complete-next-re nextnode))
-                     (and Info-complete-nodes
-                          (setq Info-complete-nodes (cdr Info-complete-nodes)
-                                nextnode (car Info-complete-nodes)))))
+                     (and complete-nodes
+                          (setq complete-nodes (cdr complete-nodes)
+                                nextnode (car complete-nodes)))))
              (Info-goto-node nextnode))
            ;; Go back to the start node (for the next completion).
            (unless (equal Info-current-node orignode)
@@ -2664,7 +2692,7 @@ following nodes whose names also contain the word \"Index\"."
   (or file (setq file Info-current-file))
   (or (assoc file Info-index-nodes)
       ;; Skip virtual Info files
-      (and (member file '("dir" "history" "toc" "apropos"))
+      (and (member file '("dir" apropos history toc))
            (setq Info-index-nodes (cons (cons file nil) Info-index-nodes)))
       (not (stringp file))
       (if Info-file-supports-index-cookies
@@ -2757,11 +2785,11 @@ If FILE is nil, check the current Info file."
 
 ;;;###autoload
 (defun Info-index (topic)
-  "Look up a string TOPIC in the index for this file.
+  "Look up a string TOPIC in the index for this manual and go to that entry.
 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 \\<Info-mode-map>\\[Info-index-next] command to see the other matches.
-Give a blank topic name to go to the Index node itself."
+Give an empty topic name to go to the Index node itself."
   (interactive
    (list
     (let ((Info-complete-menu-buffer (clone-buffer))
@@ -2906,7 +2934,7 @@ Build a menu of the possible matches."
             (message "%s" (if (eq (car-safe err) 'error)
                               (nth 1 err) err))
             (sit-for 1 t)))))
-      (Info-goto-node (concat "(" current-file ")" current-node))
+      (Info-find-node current-file current-node)
       (setq Info-history ohist
            Info-history-list ohist-list)
       (message "Searching indices...done")
@@ -2925,7 +2953,7 @@ Build a menu of the possible matches."
                     (if (nth 3 entry)
                         (concat " (line " (nth 3 entry) ")")
                       "")))))
-       (Info-find-node "apropos" "Index")
+       (Info-find-node 'apropos "Index")
        (setq Info-complete-cache nil)))))
 
 (defun Info-undefined ()
@@ -3016,7 +3044,11 @@ At end of the node's text, moves to the next node, or up if none."
 (defun Info-follow-nearest-node (&optional fork)
   "Follow a node reference near point.
 If point is on a reference, follow that reference.  Otherwise,
-if point is in a menu item description, follow that menu item."
+if point is in a menu item description, follow that menu item.
+
+If FORK is non-nil (interactively with a prefix arg), show the node in
+a new Info buffer.
+If FORK is a string, it is the name to use for the new buffer."
   (interactive "P")
   (or (Info-try-follow-nearest-node fork)
       (when (save-excursion
@@ -3071,6 +3103,7 @@ if point is in a menu item description, follow that menu item."
   (define-key Info-mode-map " " 'Info-scroll-up)
   (define-key Info-mode-map "\C-m" 'Info-follow-nearest-node)
   (define-key Info-mode-map "\t" 'Info-next-reference)
+  (define-key Info-mode-map "\e\t" 'Info-prev-reference)
   (define-key Info-mode-map [(shift tab)] 'Info-prev-reference)
   (define-key Info-mode-map [backtab] 'Info-prev-reference)
   (define-key Info-mode-map "1" 'Info-nth-menu-item)
@@ -3181,14 +3214,14 @@ if point is in a menu item description, follow that menu item."
   (if (display-graphic-p)
       (let ((map (make-sparse-keymap)))
        (tool-bar-local-item-from-menu 'Info-exit "close" map Info-mode-map)
-       (tool-bar-local-item-from-menu 'Info-prev "left-arrow" map Info-mode-map)
-       (tool-bar-local-item-from-menu 'Info-next "right-arrow" map Info-mode-map)
-       (tool-bar-local-item-from-menu 'Info-up "up-arrow" map Info-mode-map)
-       (tool-bar-local-item-from-menu 'Info-history-back "back-arrow" map Info-mode-map)
-       (tool-bar-local-item-from-menu 'Info-history-forward "fwd-arrow" map Info-mode-map)
+       (tool-bar-local-item-from-menu 'Info-history-back "left-arrow" map Info-mode-map)
+       (tool-bar-local-item-from-menu 'Info-history-forward "right-arrow" map Info-mode-map)
+       (tool-bar-local-item-from-menu 'Info-prev "prev-node" map Info-mode-map)
+       (tool-bar-local-item-from-menu 'Info-next "next-node" map Info-mode-map)
+       (tool-bar-local-item-from-menu 'Info-up "up-node" map Info-mode-map)
        (tool-bar-local-item-from-menu 'Info-top-node "home" map Info-mode-map)
-       (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map)
        (tool-bar-local-item-from-menu 'Info-goto-node "jump-to" map Info-mode-map)
+       (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map)
        (tool-bar-local-item-from-menu 'Info-search "search" map Info-mode-map)
        map)))
 
@@ -3266,14 +3299,14 @@ With a zero prefix arg, put the name inside a function call to `info'."
   (interactive "P")
   (unless Info-current-node
     (error "No current Info node"))
-  (let ((node (concat "(" (file-name-nondirectory
-                           (or (and (stringp Info-current-file)
-                                    Info-current-file)
-                               buffer-file-name
-                               ""))
-                      ")" Info-current-node)))
+  (let ((node (if (stringp Info-current-file)
+                 (concat "(" (file-name-nondirectory Info-current-file) ")"
+                         Info-current-node))))
     (if (zerop (prefix-numeric-value arg))
         (setq node (concat "(info \"" node "\")")))
+    (unless (stringp Info-current-file)
+      (setq node (format "(Info-find-node '%S '%S)"
+                        Info-current-file Info-current-node)))
     (kill-new node)
     (message "%s" node)))
 
@@ -3337,7 +3370,7 @@ Advanced commands:
 \\[Info-search-case-sensitively]       Search through this Info file for specified regexp case-sensitively.
 \\[Info-search-next]   Search for another occurrence of regexp
          from a previous \\<Info-mode-map>\\[Info-search] command.
-\\[Info-index] Look up a topic in this file's Index and move to that node.
+\\[Info-index] Search for a topic in this manual's Index and go to index entry.
 \\[Info-index-next]    (comma) Move to the next match from a previous \\<Info-mode-map>\\[Info-index] command.
 \\[info-apropos]       Look for a string in the indices of all manuals.
 \\[Info-goto-node]     Move to node specified by name.
@@ -3800,27 +3833,32 @@ the variable `Info-file-list-for-emacs'."
                                         "^[ \t]+" ""
                                         (replace-regexp-in-string
                                          "[ \t\n]+" " "
-                                         (or (match-string 5)
+                                         (or (match-string-no-properties 5)
                                              (and (not (equal (match-string 4) ""))
-                                                  (match-string 4))
-                                             (match-string 2)))))
-                                 (file (file-name-nondirectory
-                                        Info-current-file))
+                                                  (match-string-no-properties 4))
+                                             (match-string-no-properties 2)))))
+                                (external-link-p
+                                 (string-match "(\\([^)]+\\))\\([^)]*\\)" node))
+                                 (file (if external-link-p
+                                          (file-name-nondirectory
+                                           (match-string-no-properties 1 node))
+                                        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) "")
+                            (if external-link-p
+                               (setq 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))))
+                                             (match-string-no-properties 2 node))))
+                           (while hl
+                             (if (and (string-equal node (nth 1 (car hl)))
+                                      (equal file
+                                             (if (and external-link-p
+                                                      (stringp (caar hl)))
+                                                 (file-name-nondirectory
+                                                  (caar hl))
+                                               (caar 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
@@ -3910,25 +3948,31 @@ the variable `Info-file-list-for-emacs'."
                  ;; Display visited menu items in a different face
                  (if (and Info-fontify-visited-nodes
                           (save-match-data
-                            (let ((node (if (equal (match-string 3) "")
-                                            (match-string 1)
-                                          (match-string 3)))
-                                  (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) "")
+                            (let* ((node (if (equal (match-string 3) "")
+                                            (match-string-no-properties 1)
+                                          (match-string-no-properties 3)))
+                                  (external-link-p
+                                   (string-match "(\\([^)]+\\))\\([^)]*\\)" node))
+                                  (file (if external-link-p
+                                            (file-name-nondirectory
+                                             (match-string-no-properties 1 node))
+                                          Info-current-file))
+                                  (hl Info-history-list)
+                                  res)
+                              (if external-link-p
+                                  (setq 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))))
+                                               (match-string-no-properties 2 node))))
+                             (while hl
+                               (if (and (string-equal node (nth 1 (car hl)))
+                                        (equal file
+                                               (if (and external-link-p
+                                                        (stringp (caar hl)))
+                                                   (file-name-nondirectory
+                                                    (caar hl))
+                                                 (caar hl))))
+                                   (setq res (car hl) hl nil)
+                                 (setq hl (cdr hl))))
                               res))) 'info-xref-visited 'info-xref)))
              (when (and not-fontified-p (memq Info-hide-note-references '(t hide)))
                (put-text-property (match-beginning 2) (1- (match-end 6))
@@ -4121,7 +4165,7 @@ INDENT is the current indentation depth."
 NODESPEC is a string of the form: (file)node."
   (save-excursion
     ;; Set up a buffer we can use to fake-out Info.
-    (set-buffer (get-buffer-create "*info-browse-tmp*"))
+    (set-buffer (get-buffer-create " *info-browse-tmp*"))
     (if (not (equal major-mode 'Info-mode))
        (Info-mode))
     ;; Get the node into this buffer
@@ -4185,8 +4229,8 @@ BUFFER is the buffer speedbar is requesting buttons for."
 
 (defun Info-desktop-buffer-misc-data (desktop-dirname)
   "Auxiliary information to be saved in desktop file."
-  (if (not (member Info-current-file '("apropos" "history" "toc")))
-      (list Info-current-file Info-current-node)))
+  (unless (member Info-current-file '(apropos history toc nil))
+    (list Info-current-file Info-current-node)))
 
 (defun Info-restore-desktop-buffer (desktop-buffer-file-name
                                     desktop-buffer-name