authors.el: Add some renamed/moved files
[bpt/emacs.git] / lisp / info.el
index 9dc312f..2b2490b 100644 (file)
@@ -1,8 +1,8 @@
 ;; info.el --- info package for Emacs
 
-;; Copyright (C) 1985-1986, 1992-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1985-1986, 1992-2014 Free Software Foundation, Inc.
 
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: help
 
 ;; This file is part of GNU Emacs.
@@ -790,7 +790,7 @@ See a list of available Info commands in `Info-mode'."
 
 (defun info-setup (file-or-node buffer)
   "Display Info node FILE-OR-NODE in BUFFER."
-  (if (and buffer (not (eq major-mode 'Info-mode)))
+  (if (and buffer (not (derived-mode-p 'Info-mode)))
       (Info-mode))
   (if file-or-node
       ;; If argument already contains parentheses, don't add another set
@@ -917,23 +917,30 @@ just return nil (no error)."
          (setq filename found)
        (if noerror
            (setq filename nil)
-         (error "Info file %s does not exist" filename)))
+         ;; If there is no previous Info file, go to the directory.
+         (unless Info-current-file
+           (Info-directory))
+         (user-error "Info file %s does not exist" filename)))
       filename))))
 
-(defun Info-find-node (filename nodename &optional no-going-back)
+(defun Info-find-node (filename nodename &optional no-going-back strict-case)
   "Go to an Info node specified as separate FILENAME and NODENAME.
 NO-GOING-BACK is non-nil if recovering from an error in this function;
-it says do not attempt further (recursive) error recovery."
+it says do not attempt further (recursive) error recovery.
+
+This function first looks for a case-sensitive match for NODENAME;
+if none is found it then tries a case-insensitive match (unless
+STRICT-CASE is non-nil)."
   (info-initialize)
   (setq filename (Info-find-file filename))
   ;; Go into Info buffer.
-  (or (eq major-mode 'Info-mode) (switch-to-buffer "*info*"))
+  (or (derived-mode-p 'Info-mode) (switch-to-buffer "*info*"))
   ;; Record the node we are leaving, if we were in one.
   (and (not no-going-back)
        Info-current-file
        (push (list Info-current-file Info-current-node (point))
              Info-history))
-  (Info-find-node-2 filename nodename no-going-back))
+  (Info-find-node-2 filename nodename no-going-back strict-case))
 
 ;;;###autoload
 (defun Info-on-current-buffer (&optional nodename)
@@ -957,7 +964,7 @@ otherwise, that defaults to `Top'."
   "Go to an Info node FILENAME and NODENAME, re-reading disk contents.
 When *info* is already displaying FILENAME and NODENAME, the window position
 is preserved, if possible."
-  (or (eq major-mode 'Info-mode) (switch-to-buffer "*info*"))
+  (or (derived-mode-p 'Info-mode) (switch-to-buffer "*info*"))
   (let ((old-filename Info-current-file)
        (old-nodename Info-current-node)
        (window-selected (eq (selected-window) (get-buffer-window)))
@@ -1010,7 +1017,7 @@ which the match was found."
              (+ (point-min) (read (current-buffer)))
              major-mode)))))
 
-(defun Info-find-in-tag-table (marker regexp)
+(defun Info-find-in-tag-table (marker regexp &optional strict-case)
   "Find a node in a tag table.
 MARKER specifies the buffer and position to start searching at.
 REGEXP is a regular expression matching nodes or references.  Its first
@@ -1020,10 +1027,11 @@ FOUND-ANCHOR is non-nil if a `Ref:' was matched, POS is the position
 where the match was found, and MODE is `major-mode' of the buffer in
 which the match was found.
 This function tries to find a case-sensitive match first, then a
-case-insensitive match is tried."
+case-insensitive match is tried (unless optional argument STRICT-CASE
+is non-nil)."
   (let ((result (Info-find-in-tag-table-1 marker regexp nil)))
-    (when (null (car result))
-      (setq result (Info-find-in-tag-table-1 marker regexp t)))
+    (or strict-case (car result)
+       (setq result (Info-find-in-tag-table-1 marker regexp t)))
     result))
 
 (defun Info-find-node-in-buffer-1 (regexp case-fold)
@@ -1046,19 +1054,21 @@ Value is the position at which a match was found, or nil if not found."
                 (setq found (line-beginning-position)))))))
     found))
 
-(defun Info-find-node-in-buffer (regexp)
+(defun Info-find-node-in-buffer (regexp &optional strict-case)
   "Find a node or anchor in the current buffer.
 REGEXP is a regular expression matching nodes or references.  Its first
 group should match `Node:' or `Ref:'.
 Value is the position at which a match was found, or nil if not found.
 This function looks for a case-sensitive match first.  If none is found,
-a case-insensitive match is tried."
+a case-insensitive match is tried (unless optional argument STRICT-CASE
+is non-nil)."
   (or (Info-find-node-in-buffer-1 regexp nil)
-      (Info-find-node-in-buffer-1 regexp t)))
+      (and (not strict-case)
+          (Info-find-node-in-buffer-1 regexp t))))
 
-(defun Info-find-node-2 (filename nodename &optional no-going-back)
+(defun Info-find-node-2 (filename nodename &optional no-going-back strict-case)
   (buffer-disable-undo (current-buffer))
-  (or (eq major-mode 'Info-mode)
+  (or (derived-mode-p 'Info-mode)
       (Info-mode))
   (widen)
   (setq Info-current-node nil)
@@ -1167,7 +1177,7 @@ a case-insensitive match is tried."
              ;; First, search a tag table, if any
              (when (marker-position Info-tag-table-marker)
                (let* ((m Info-tag-table-marker)
-                      (found (Info-find-in-tag-table m regexp)))
+                      (found (Info-find-in-tag-table m regexp strict-case)))
 
                  (when found
                    ;; FOUND is (ANCHOR POS MODE).
@@ -1194,7 +1204,7 @@ a case-insensitive match is tried."
              ;; buffer) to find the actual node.  First, check
              ;; whether the node is right where we are, in case the
              ;; buffer begins with a node.
-             (let ((pos (Info-find-node-in-buffer regexp)))
+             (let ((pos (Info-find-node-in-buffer regexp strict-case)))
                (when pos
                  (goto-char pos)
                  (throw 'foo t)))
@@ -1230,12 +1240,14 @@ a case-insensitive match is tried."
                   (Info-find-index-name Info-point-loc)
                   (setq Info-point-loc nil))))))
     ;; If we did not finish finding the specified node,
-    ;; go back to the previous one.
-    (or Info-current-node no-going-back (null Info-history)
-        (let ((hist (car Info-history)))
-          (setq Info-history (cdr Info-history))
-          (Info-find-node (nth 0 hist) (nth 1 hist) t)
-          (goto-char (nth 2 hist))))))
+    ;; go back to the previous one or to the Top node.
+    (unless (or Info-current-node no-going-back)
+      (if Info-history
+         (let ((hist (car Info-history)))
+           (setq Info-history (cdr Info-history))
+           (Info-find-node (nth 0 hist) (nth 1 hist) t)
+           (goto-char (nth 2 hist)))
+       (Info-find-node Info-current-file "Top" t)))))
 
 ;; Cache the contents of the (virtual) dir file, once we have merged
 ;; it for the first time, so we can save time subsequently.
@@ -1588,17 +1600,20 @@ escaped (\\\",\\\\)."
                                    ""))
                      (image (if (file-exists-p image-file)
                                 (create-image image-file)
-                              "[broken image]")))
+                              (or (cdr (assoc-string "text" parameter-alist))
+                                 (and src (concat "[broken image:" src "]"))
+                                 "[broken image]"))))
                 (if (not (get-text-property start 'display))
                     (add-text-properties
-                     start (point) `(display ,image rear-nonsticky (display)))))
+                     start (point)
+                    `(display ,image rear-nonsticky (display)
+                      help-echo ,(cdr (assoc-string "alt" parameter-alist))))))
             ;; text-only display, show alternative text if provided, or
             ;; otherwise a clue that there's meant to be a picture
             (delete-region start (point))
             (insert (or (cdr (assoc-string "text" parameter-alist))
                         (cdr (assoc-string "alt" parameter-alist))
-                        (and src
-                             (concat "[image:" src "]"))
+                        (and src (concat "[image:" src "]"))
                         "[image]"))))))
     (set-buffer-modified-p nil)))
 
@@ -1701,7 +1716,7 @@ escaped (\\\",\\\\)."
 ;; Don't autoload this function: the correct entry point for other packages
 ;; to use is `info'.  --Stef
 ;; ;;;###autoload
-(defun Info-goto-node (nodename &optional fork)
+(defun Info-goto-node (nodename &optional fork strict-case)
   "Go to Info node named NODENAME.  Give just NODENAME or (FILENAME)NODENAME.
 If NODENAME is of the form (FILENAME)NODENAME, the node is in the Info file
 FILENAME; otherwise, NODENAME should be in the current Info file (or one of
@@ -1711,7 +1726,11 @@ in the Info file FILENAME after the closing parenthesis in (FILENAME).
 Empty NODENAME in (FILENAME) defaults to the Top node.
 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."
+If FORK is a string, it is the name to use for the new buffer.
+
+This function first looks for a case-sensitive match for the node part
+of NODENAME; if none is found it then tries a case-insensitive match
+\(unless STRICT-CASE is non-nil)."
   (interactive (list (Info-read-node-name "Go to node: ") current-prefix-arg))
   (info-initialize)
   (if fork
@@ -1730,7 +1749,7 @@ If FORK is a string, it is the name to use for the new buffer."
       (if trim (setq nodename (substring nodename 0 trim))))
     (if transient-mark-mode (deactivate-mark))
     (Info-find-node (if (equal filename "") nil filename)
-                   (if (equal nodename "") "Top" nodename))))
+                   (if (equal nodename "") "Top" nodename) nil strict-case)))
 
 (defvar Info-read-node-completion-table)
 
@@ -1894,6 +1913,30 @@ the Top node in FILENAME."
 (defvar Info-search-case-fold nil
   "The value of `case-fold-search' from previous `Info-search' command.")
 
+(defun Info--search-loop (regexp bound backward)
+  (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)))
+  (let ((give-up nil)
+        (found nil)
+        (beg-found nil))
+    (while (not (or give-up
+                    (and found
+                         (funcall isearch-filter-predicate
+                                  beg-found found))))
+      (let ((search-spaces-regexp Info-search-whitespace-regexp))
+        (if (funcall
+             (if backward #'re-search-backward #'re-search-forward)
+             regexp bound t)
+            (setq found (point) beg-found (if backward (match-end 0)
+                                            (match-beginning 0)))
+          (setq give-up t found nil))))
+    found))
+
 (defun Info-search (regexp &optional bound _noerror _count direction)
   "Search for REGEXP, starting from point, and select node it's found in.
 If DIRECTION is `backward', search in the reverse direction."
@@ -1909,55 +1952,35 @@ If DIRECTION is `backward', search in the reverse direction."
   (when (equal regexp "")
     (setq regexp (car Info-search-history)))
   (when regexp
-    (let (found beg-found give-up
-         (backward (eq direction 'backward))
-         (onode Info-current-node)
-         (ofile Info-current-file)
-         (opoint (point))
-         (opoint-min (point-min))
-         (opoint-max (point-max))
-         (ostart (window-start))
-         (osubfile Info-current-subfile))
-      (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)
-                         (not (run-hook-with-args-until-failure
-                               'isearch-filter-predicates beg-found found))))
-           (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))))))
-
-      (when (and isearch-mode Info-isearch-search
-                (not Info-isearch-initial-node)
-                (not bound)
-                (or give-up (and found (not (and (> found opoint-min)
-                                                 (< found opoint-max))))))
+    (setq Info-search-case-fold case-fold-search)
+    (let* ((backward (eq direction 'backward))
+           (onode Info-current-node)
+           (ofile Info-current-file)
+           (opoint (point))
+           (opoint-min (point-min))
+           (opoint-max (point-max))
+           (ostart (window-start))
+           (osubfile Info-current-subfile)
+           (found
+            (save-excursion
+              (save-restriction
+                (widen)
+                (Info--search-loop regexp bound backward)))))
+
+      (unless (or (not isearch-mode) (not Info-isearch-search)
+                  Info-isearch-initial-node
+                  bound
+                  (and found (> found opoint-min) (< found opoint-max)))
        (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 Info-search-whitespace-regexp))
-                 (if backward
-                     (re-search-backward regexp)
-                   (re-search-forward regexp))))
-           (setq found nil)))
+      (unless (or found Info-current-subfile)
+        (if isearch-mode
+            (signal 'search-failed (list regexp "end of manual"))
+          (let ((search-spaces-regexp Info-search-whitespace-regexp))
+            (if backward
+                (re-search-backward regexp)
+              (re-search-forward regexp)))))
 
       (if (and bound (not found))
          (signal 'search-failed (list regexp)))
@@ -1998,29 +2021,9 @@ If DIRECTION is `backward', search in the reverse direction."
              (while list
                (message "Searching subfile %s..." (cdr (car list)))
                (Info-read-subfile (car (car list)))
-               (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)))
+               (when backward (goto-char (point-max)))
                (setq list (cdr list))
-               (setq give-up nil found nil)
-               (while (and (not give-up)
-                           (or (null found)
-                               (not (run-hook-with-args-until-failure
-                                     'isearch-filter-predicates beg-found found))))
-                 (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))
+                (setq found (Info--search-loop regexp nil backward))
                (if found
                    (setq list nil)))
              (if found
@@ -2214,7 +2217,7 @@ End of submatch 0, 1, and 3 are the same, so you can safely concat."
   (interactive)
   ;; In case another window is currently selected
   (save-window-excursion
-    (or (eq major-mode 'Info-mode) (switch-to-buffer "*info*"))
+    (or (derived-mode-p 'Info-mode) (switch-to-buffer "*info*"))
     (Info-goto-node (Info-extract-pointer "next"))))
 
 (defun Info-prev ()
@@ -2222,7 +2225,7 @@ End of submatch 0, 1, and 3 are the same, so you can safely concat."
   (interactive)
   ;; In case another window is currently selected
   (save-window-excursion
-    (or (eq major-mode 'Info-mode) (switch-to-buffer "*info*"))
+    (or (derived-mode-p 'Info-mode) (switch-to-buffer "*info*"))
     (Info-goto-node (Info-extract-pointer "prev[ious]*" "previous"))))
 
 (defun Info-up (&optional same-file)
@@ -2231,7 +2234,7 @@ If SAME-FILE is non-nil, do not move to a different Info file."
   (interactive)
   ;; In case another window is currently selected
   (save-window-excursion
-    (or (eq major-mode 'Info-mode) (switch-to-buffer "*info*"))
+    (or (derived-mode-p 'Info-mode) (switch-to-buffer "*info*"))
     (let ((old-node Info-current-node)
          (old-file Info-current-file)
          (node (Info-extract-pointer "up")) p)
@@ -3695,7 +3698,9 @@ Build a menu of the possible matches."
          hits desc)
       (dolist (keyword keywords)
        (push (copy-tree (gethash keyword finder-keywords-hash)) hits))
-      (setq hits (delete-dups (apply 'append hits)))
+      (setq hits (delete-dups (apply 'append hits))
+           ;; Not a meaningful package.
+           hits (delete 'emacs hits))
       (dolist (package hits)
        (setq desc (cdr-safe (assq package package--builtins)))
        (when (vectorp desc)
@@ -3710,6 +3715,9 @@ Build a menu of the possible matches."
     (insert "*****************\n\n")
     (insert
      "Commentary section of the package `" nodename "':\n\n")
+    ;; FIXME this assumes that a file named package.el exists,
+    ;; which is not always true.  E.g. for the nxml package,
+    ;; there is no "nxml.el" (it's nxml-mode.el).
     (let ((str (lm-commentary (find-library-name nodename))))
       (if (null str)
          (insert "Can't find any Commentary section\n\n")
@@ -3870,23 +3878,6 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
      ((setq node (Info-get-token (point) "\\*note[ \n\t]+"
                                 "\\*note[ \n\t]+\\([^:]*\\):\\(:\\|[ \n\t]*(\\)?"))
       (Info-follow-reference node fork))
-     ;; menu item: node name
-     ((setq node (Info-get-token (point) "\\* +" "\\* +\\([^:]*\\)::"))
-      (Info-goto-node node fork))
-     ;; menu item: node name or index entry
-     ((Info-get-token (point) "\\* +" "\\* +\\(.*\\): ")
-      (beginning-of-line)
-      (forward-char 2)
-      (setq node (Info-extract-menu-node-name nil (Info-index-node)))
-      (Info-goto-node node fork))
-     ((setq node (Info-get-token (point) "Up: " "Up: \\([^,\n\t]*\\)"))
-      (Info-goto-node node fork))
-     ((setq node (Info-get-token (point) "Next: " "Next: \\([^,\n\t]*\\)"))
-      (Info-goto-node node fork))
-     ((setq node (Info-get-token (point) "File: " "File: \\([^,\n\t]*\\)"))
-      (Info-goto-node "Top" fork))
-     ((setq node (Info-get-token (point) "Prev: " "Prev: \\([^,\n\t]*\\)"))
-      (Info-goto-node node fork))
      ;; footnote
      ((setq node (Info-get-token (point) "(" "\\(([0-9]+)\\)"))
       (let ((old-point (point)) new-point)
@@ -3904,7 +3895,24 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
            (progn
              (goto-char new-point)
              (setq node t))
-         (setq node nil)))))
+         (setq node nil))))
+     ;; menu item: node name
+     ((setq node (Info-get-token (point) "\\* +" "\\* +\\([^:]*\\)::"))
+      (Info-goto-node node fork))
+     ;; menu item: node name or index entry
+     ((Info-get-token (point) "\\* +" "\\* +\\(.*\\): ")
+      (beginning-of-line)
+      (forward-char 2)
+      (setq node (Info-extract-menu-node-name nil (Info-index-node)))
+      (Info-goto-node node fork))
+     ((setq node (Info-get-token (point) "Up: " "Up: \\([^,\n\t]*\\)"))
+      (Info-goto-node node fork))
+     ((setq node (Info-get-token (point) "Next: " "Next: \\([^,\n\t]*\\)"))
+      (Info-goto-node node fork))
+     ((setq node (Info-get-token (point) "File: " "File: \\([^,\n\t]*\\)"))
+      (Info-goto-node "Top" fork))
+     ((setq node (Info-get-token (point) "Prev: " "Prev: \\([^,\n\t]*\\)"))
+      (Info-goto-node node fork)))
     node))
 
 (defun Info-mouse-follow-link (click)
@@ -3959,6 +3967,10 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
     (define-key map "f" 'Info-follow-reference)
     (define-key map "g" 'Info-goto-node)
     (define-key map "h" 'Info-help)
+    ;; This is for compatibility with standalone info (>~ version 5.2).
+    ;; Though for some time, standalone info had H and h reversed.
+    ;; See <http://debbugs.gnu.org/16455>.
+    (define-key map "H" 'describe-mode)
     (define-key map "i" 'Info-index)
     (define-key map "I" 'Info-virtual-index)
     (define-key map "l" 'Info-history-back)
@@ -4084,7 +4096,7 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
 (defun Info-menu-update ()
   "Update the Info menu for the current node."
   (condition-case nil
-      (if (or (not (eq major-mode 'Info-mode))
+      (if (or (not (derived-mode-p 'Info-mode))
              (equal (list Info-current-file Info-current-node)
                     Info-menu-last-node))
          ()
@@ -4277,8 +4289,7 @@ Advanced commands:
        'Info-isearch-wrap)
   (set (make-local-variable 'isearch-push-state-function)
        'Info-isearch-push-state)
-  (set (make-local-variable 'isearch-filter-predicates)
-       '(Info-isearch-filter))
+  (set (make-local-variable 'isearch-filter-predicate) #'Info-isearch-filter)
   (set (make-local-variable 'revert-buffer-function)
        'Info-revert-buffer-function)
   (Info-set-mode-line)
@@ -4288,7 +4299,7 @@ Advanced commands:
 ;; When an Info buffer is killed, make sure the associated tags buffer
 ;; is killed too.
 (defun Info-kill-buffer ()
-  (and (eq major-mode 'Info-mode)
+  (and (derived-mode-p 'Info-mode)
        Info-tag-table-buffer
        (kill-buffer Info-tag-table-buffer)))
 
@@ -4305,10 +4316,11 @@ Advanced commands:
                  (copy-marker (marker-position m)))
              (make-marker))))))
 
-(defvar Info-edit-map (let ((map (make-sparse-keymap)))
-                       (set-keymap-parent map text-mode-map)
-                       (define-key map "\C-c\C-c" 'Info-cease-edit)
-                       map)
+(define-obsolete-variable-alias 'Info-edit-map 'Info-edit-mode-map "24.1")
+(defvar Info-edit-mode-map (let ((map (make-sparse-keymap)))
+                             (set-keymap-parent map text-mode-map)
+                             (define-key map "\C-c\C-c" 'Info-cease-edit)
+                             map)
   "Local keymap used within `e' command of Info.")
 
 (make-obsolete-variable 'Info-edit-map
@@ -4318,19 +4330,14 @@ Advanced commands:
 ;; Info-edit mode is suitable only for specially formatted data.
 (put 'Info-edit-mode 'mode-class 'special)
 
-(defun Info-edit-mode ()
+(define-derived-mode Info-edit-mode text-mode "Info Edit"
   "Major mode for editing the contents of an Info node.
 Like text mode with the addition of `Info-cease-edit'
 which returns to Info mode for browsing.
 \\{Info-edit-map}"
-  (use-local-map Info-edit-map)
-  (setq major-mode 'Info-edit-mode)
-  (setq mode-name "Info Edit")
-  (kill-local-variable 'mode-line-buffer-identification)
   (setq buffer-read-only nil)
   (force-mode-line-update)
-  (buffer-enable-undo (current-buffer))
-  (run-mode-hooks 'Info-edit-mode-hook))
+  (buffer-enable-undo (current-buffer)))
 
 (make-obsolete 'Info-edit-mode
               "editing Info nodes by hand is not recommended." "24.4")
@@ -4355,11 +4362,7 @@ This feature will be removed in future.")
   (and (buffer-modified-p)
        (y-or-n-p "Save the file? ")
        (save-buffer))
-  (use-local-map Info-mode-map)
-  (setq major-mode 'Info-mode)
-  (setq mode-name "Info")
-  (Info-set-mode-line)
-  (setq buffer-read-only t)
+  (Info-mode)
   (force-mode-line-update)
   (and (marker-position Info-tag-table-marker)
        (buffer-modified-p)
@@ -4472,7 +4475,7 @@ COMMAND must be a symbol or string."
          ;; Get Info running, and pop to it in another window.
          (save-window-excursion
            (info))
-         (or (eq major-mode 'Info-mode) (pop-to-buffer "*info*"))
+         (or (derived-mode-p 'Info-mode) (pop-to-buffer "*info*"))
          ;; Bind Info-history to nil, to prevent the last Index node
          ;; visited by Info-find-emacs-command-nodes from being
          ;; pushed onto the history.
@@ -5136,7 +5139,7 @@ INDENT is the current indentation depth."
 NODESPEC is a string of the form: (file)node."
   ;; Set up a buffer we can use to fake-out Info.
   (with-current-buffer (get-buffer-create " *info-browse-tmp*")
-    (if (not (equal major-mode 'Info-mode))
+    (if (not (derived-mode-p 'Info-mode))
        (Info-mode))
     ;; Get the node into this buffer
     (if (not (string-match "^(\\([^)]+\\))\\([^.]+\\)$" nodespec))