Unset EMACSLOADPATH in some Makefiles rather than setting it to the default
[bpt/emacs.git] / lisp / info.el
index b467373..9344268 100644 (file)
@@ -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."
 
 (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
       (Info-mode))
   (if file-or-node
       ;; If argument already contains parentheses, don't add another set
@@ -920,20 +920,24 @@ just return nil (no error)."
          (error "Info file %s does not exist" filename)))
       filename))))
 
          (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;
   "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.
   (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))
   ;; 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)
 
 ;;;###autoload
 (defun Info-on-current-buffer (&optional nodename)
@@ -957,7 +961,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."
   "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)))
   (let ((old-filename Info-current-file)
        (old-nodename Info-current-node)
        (window-selected (eq (selected-window) (get-buffer-window)))
@@ -1010,7 +1014,7 @@ which the match was found."
              (+ (point-min) (read (current-buffer)))
              major-mode)))))
 
              (+ (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
   "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 +1024,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
 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)))
   (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)
     result))
 
 (defun Info-find-node-in-buffer-1 (regexp case-fold)
@@ -1046,19 +1051,21 @@ Value is the position at which a match was found, or nil if not found."
                 (setq found (line-beginning-position)))))))
     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,
   "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)
   (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))
   (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)
       (Info-mode))
   (widen)
   (setq Info-current-node nil)
@@ -1167,7 +1174,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)
              ;; 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).
 
                  (when found
                    ;; FOUND is (ANCHOR POS MODE).
@@ -1194,7 +1201,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.
              ;; 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)))
                (when pos
                  (goto-char pos)
                  (throw 'foo t)))
@@ -1588,17 +1595,20 @@ escaped (\\\",\\\\)."
                                    ""))
                      (image (if (file-exists-p image-file)
                                 (create-image image-file)
                                    ""))
                      (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
                 (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))
             ;; 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)))
 
                         "[image]"))))))
     (set-buffer-modified-p nil)))
 
@@ -1701,7 +1711,7 @@ escaped (\\\",\\\\)."
 ;; Don't autoload this function: the correct entry point for other packages
 ;; to use is `info'.  --Stef
 ;; ;;;###autoload
 ;; 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
   "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 +1721,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.
 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
   (interactive (list (Info-read-node-name "Go to node: ") current-prefix-arg))
   (info-initialize)
   (if fork
@@ -1730,7 +1744,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 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)
 
 
 (defvar Info-read-node-completion-table)
 
@@ -1894,6 +1908,30 @@ the Top node in FILENAME."
 (defvar Info-search-case-fold nil
   "The value of `case-fold-search' from previous `Info-search' command.")
 
 (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."
 (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,54 +1947,35 @@ If DIRECTION is `backward', search in the reverse direction."
   (when (equal regexp "")
     (setq regexp (car Info-search-history)))
   (when regexp
   (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 (funcall isearch-filter-predicate 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.
        (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)))
 
       (if (and bound (not found))
          (signal 'search-failed (list regexp)))
@@ -1997,28 +2016,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)))
              (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 list (cdr list))
-               (setq give-up nil found nil)
-               (while (and (not give-up)
-                           (or (null found)
-                               (not (funcall isearch-filter-predicate 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
                (if found
                    (setq list nil)))
              (if found
@@ -2212,7 +2212,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
   (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 ()
     (Info-goto-node (Info-extract-pointer "next"))))
 
 (defun Info-prev ()
@@ -2220,7 +2220,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
   (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)
     (Info-goto-node (Info-extract-pointer "prev[ious]*" "previous"))))
 
 (defun Info-up (&optional same-file)
@@ -2229,7 +2229,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
   (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)
     (let ((old-node Info-current-node)
          (old-file Info-current-file)
          (node (Info-extract-pointer "up")) p)
@@ -3868,23 +3868,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))
      ((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)
      ;; footnote
      ((setq node (Info-get-token (point) "(" "\\(([0-9]+)\\)"))
       (let ((old-point (point)) new-point)
@@ -3902,7 +3885,24 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
            (progn
              (goto-char new-point)
              (setq node t))
            (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)
     node))
 
 (defun Info-mouse-follow-link (click)
@@ -4082,7 +4082,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
 (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))
          ()
              (equal (list Info-current-file Info-current-node)
                     Info-menu-last-node))
          ()
@@ -4275,8 +4275,7 @@ Advanced commands:
        'Info-isearch-wrap)
   (set (make-local-variable 'isearch-push-state-function)
        'Info-isearch-push-state)
        'Info-isearch-wrap)
   (set (make-local-variable 'isearch-push-state-function)
        'Info-isearch-push-state)
-  (set (make-local-variable 'isearch-filter-predicate)
-       '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)
   (set (make-local-variable 'revert-buffer-function)
        'Info-revert-buffer-function)
   (Info-set-mode-line)
@@ -4286,7 +4285,7 @@ Advanced commands:
 ;; When an Info buffer is killed, make sure the associated tags buffer
 ;; is killed too.
 (defun Info-kill-buffer ()
 ;; 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)))
 
        Info-tag-table-buffer
        (kill-buffer Info-tag-table-buffer)))
 
@@ -4303,10 +4302,11 @@ Advanced commands:
                  (copy-marker (marker-position m)))
              (make-marker))))))
 
                  (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
   "Local keymap used within `e' command of Info.")
 
 (make-obsolete-variable 'Info-edit-map
@@ -4316,19 +4316,14 @@ Advanced commands:
 ;; Info-edit mode is suitable only for specially formatted data.
 (put 'Info-edit-mode 'mode-class 'special)
 
 ;; 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}"
   "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)
   (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")
 
 (make-obsolete 'Info-edit-mode
               "editing Info nodes by hand is not recommended." "24.4")
@@ -4353,11 +4348,7 @@ This feature will be removed in future.")
   (and (buffer-modified-p)
        (y-or-n-p "Save the file? ")
        (save-buffer))
   (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)
   (force-mode-line-update)
   (and (marker-position Info-tag-table-marker)
        (buffer-modified-p)
@@ -4470,7 +4461,7 @@ COMMAND must be a symbol or string."
          ;; Get Info running, and pop to it in another window.
          (save-window-excursion
            (info))
          ;; 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.
          ;; Bind Info-history to nil, to prevent the last Index node
          ;; visited by Info-find-emacs-command-nodes from being
          ;; pushed onto the history.
@@ -5134,7 +5125,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*")
 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))
        (Info-mode))
     ;; Get the node into this buffer
     (if (not (string-match "^(\\([^)]+\\))\\([^.]+\\)$" nodespec))