X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/f7ff1b0f0792f1f870778404531e68e77832c4a1..758c81e87ded2bad9f5a5a6683fb498965eb508c:/lisp/info.el?ds=sidebyside diff --git a/lisp/info.el b/lisp/info.el index 796fd7e225..367d9d0a9e 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -1,6 +1,6 @@ ;; info.el --- info package for Emacs -;; Copyright (C) 1985-1986, 1992-2011 Free Software Foundation, Inc. +;; Copyright (C) 1985-1986, 1992-2012 Free Software Foundation, Inc. ;; Maintainer: FSF ;; Keywords: help @@ -32,7 +32,7 @@ ;;; Code: -(eval-when-compile (require 'jka-compr) (require 'cl)) +(eval-when-compile (require 'cl)) (defgroup info nil "Info subsystem." @@ -52,6 +52,15 @@ Each element of the stack is a list (FILENAME NODENAME BUFFERPOS).") "List of all Info nodes user has visited. Each element of the list is a list (FILENAME NODENAME).") +(defcustom Info-history-skip-intermediate-nodes t + "Non-nil means don't record intermediate Info nodes to the history. +Intermediate Info nodes are nodes visited by Info internally in the process of +searching the node to display. Intermediate nodes are not presented +to the user." + :type 'boolean + :group 'info + :version "24.1") + (defcustom Info-enable-edit nil "Non-nil means the \\\\[Info-edit] command in Info can edit the current node. This is convenient if you want to write Info files by hand. @@ -222,6 +231,12 @@ want to set `Info-refill-paragraphs'." (const :tag "Replace tag and hide reference" t) (const :tag "Hide tag and reference" hide) (other :tag "Only replace tag" tag)) + :set (lambda (sym val) + (set sym val) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when (eq major-mode 'Info-mode) + (revert-buffer t t))))) :group 'info) (defcustom Info-refill-paragraphs nil @@ -255,7 +270,7 @@ Before leaving the initial Info node, where isearch was started, it fails once with the error message [initial node], and with subsequent C-s/C-r continues through other nodes without failing with this error message in other nodes. When isearch fails for -the rest of the manual, it wraps aroung the whole manual and +the rest of the manual, it wraps around the whole manual and restarts the search from the top/final node depending on search direction. @@ -464,6 +479,7 @@ be last in the list.") "Insert the contents of an Info file in the current buffer. Do the right thing if the file has been compressed or zipped." (let* ((tail Info-suffix-list) + (jka-compr-verbose nil) (lfn (if (fboundp 'msdos-long-file-names) (msdos-long-file-names) t)) @@ -539,7 +555,7 @@ in `Info-file-supports-index-cookies-list'." (condition-case () (if (and (re-search-forward "makeinfo[ \n]version[ \n]\\([0-9]+.[0-9]+\\)" - (line-beginning-position 3) t) + (line-beginning-position 4) t) (not (version< (match-string 1) "4.7"))) (setq found t)) (error nil)) @@ -609,10 +625,7 @@ in `Info-file-supports-index-cookies-list'." "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-or-node))) - -;;;###autoload (add-hook 'same-window-regexps (purecopy "\\*info\\*\\(\\|<[0-9]+>\\)")) + (info-setup file-or-node (switch-to-buffer-other-window "*info*"))) ;;;###autoload (put 'info 'info-file (purecopy "emacs")) ;;;###autoload @@ -621,7 +634,7 @@ in `Info-file-supports-index-cookies-list'." Optional argument FILE-OR-NODE specifies the file to examine; the default is the top-level directory of Info. Called from a program, FILE-OR-NODE may specify an Info node of the form -`(FILENAME)NODENAME'. +\"(FILENAME)NODENAME\". Optional argument BUFFER specifies the Info buffer name; the default buffer name is *info*. If BUFFER exists, just switch to BUFFER. Otherwise, create a new buffer @@ -642,7 +655,11 @@ See a list of available Info commands in `Info-mode'." (read-file-name "Info file name: " nil nil t)) (if (numberp current-prefix-arg) (format "*info*<%s>" current-prefix-arg)))) - (pop-to-buffer (or buffer "*info*")) + (info-setup file-or-node + (pop-to-buffer-same-window (or buffer "*info*")))) + +(defun info-setup (file-or-node buffer) + "Display Info node FILE-OR-NODE in BUFFER." (if (and buffer (not (eq major-mode 'Info-mode))) (Info-mode)) (if file-or-node @@ -665,6 +682,12 @@ See a list of available Info commands in `Info-mode'." (interactive) (info "emacs")) +;;;###autoload +(defun info-emacs-bug () + "Display the \"Reporting Bugs\" section of the Emacs manual in Info mode." + (interactive) + (info "(emacs)Bugs")) + ;;;###autoload (defun info-standalone () "Run Emacs as a standalone Info reader. @@ -728,6 +751,11 @@ just return nil (no error)." (append Info-directory-list Info-additional-directory-list) Info-directory-list))))) + ;; Fall back on the installation directory if we can't find + ;; the info node anywhere else. + (when installation-directory + (setq dirs (append dirs (list (expand-file-name + "info" installation-directory))))) ;; Search the directory list for file FILENAME. (while (and dirs (not found)) (setq temp (expand-file-name filename (car dirs))) @@ -769,7 +797,7 @@ it says do not attempt further (recursive) error recovery." (info-initialize) (setq filename (Info-find-file filename)) ;; Go into Info buffer. - (or (eq major-mode 'Info-mode) (pop-to-buffer "*info*")) + (or (eq major-mode '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 @@ -795,38 +823,30 @@ otherwise, that defaults to `Top'." (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, -;; but at least it keeps this routine (which is for makeinfo-buffer and -;; Info-revert-buffer-function) out of the way of normal operations. -;; (defun Info-revert-find-node (filename nodename) "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) (pop-to-buffer "*info*")) + (or (eq major-mode 'Info-mode) (switch-to-buffer "*info*")) (let ((old-filename Info-current-file) (old-nodename Info-current-node) - (old-buffer-name (buffer-name)) + (window-selected (eq (selected-window) (get-buffer-window))) (pcolumn (current-column)) (pline (count-lines (point-min) (line-beginning-position))) (wline (count-lines (point-min) (window-start))) - (old-history-forward Info-history-forward) - (old-history Info-history) (new-history (and Info-current-file (list Info-current-file Info-current-node (point))))) - (kill-buffer (current-buffer)) - (pop-to-buffer (or old-buffer-name "*info*")) - (Info-mode) + ;; When `Info-current-file' is nil, `Info-find-node-2' rereads the file. + (setq Info-current-file nil) (Info-find-node filename nodename) - (setq Info-history-forward old-history-forward) - (setq Info-history old-history) (if (and (equal old-filename Info-current-file) (equal old-nodename Info-current-node)) (progn ;; note goto-line is no good, we want to measure from point-min - (goto-char (point-min)) - (forward-line wline) - (set-window-start (selected-window) (point)) + (when window-selected + (goto-char (point-min)) + (forward-line wline) + (set-window-start (selected-window) (point))) (goto-char (point-min)) (forward-line pline) (move-to-column pcolumn)) @@ -1057,7 +1077,7 @@ a case-insensitive match is tried." (throw 'foo t)) ;; No such anchor in tag table or node in tag table or file - (error "No such node or anchor: %s" nodename)) + (user-error "No such node or anchor: %s" nodename)) (Info-select-node) (goto-char (point-min)) @@ -1071,7 +1091,7 @@ a case-insensitive match is tried." ;; Add anchors to the history too (setq Info-history-list (cons new-history - (delete new-history Info-history-list)))) + (remove new-history Info-history-list)))) (goto-char anchorpos)) ((numberp Info-point-loc) (forward-line (- Info-point-loc 2)) @@ -1151,6 +1171,12 @@ a case-insensitive match is tried." (progn (setq file (expand-file-name "dir.info" truename)) (file-attributes file)) (progn (setq file (expand-file-name "DIR.INFO" truename)) + (file-attributes file)) + ;; Shouldn't really happen, but sometimes does, + ;; eg on Debian systems with buggy packages; + ;; so may as well try it. + ;; http://lists.gnu.org/archive/html/emacs-devel/2012-03/msg00005.html + (progn (setq file (expand-file-name "dir.gz" truename)) (file-attributes file))))) (setq dirs-done (cons truename @@ -1498,7 +1524,7 @@ escaped (\\\",\\\\)." ;; Add a new unique history item to full history list (let ((new-history (list Info-current-file Info-current-node))) (setq Info-history-list - (cons new-history (delete new-history Info-history-list))) + (cons new-history (remove new-history Info-history-list))) (setq Info-history-forward nil)) (if (not (eq Info-fontify-maximum-menu-size nil)) (Info-fontify-node)) @@ -1572,7 +1598,12 @@ If FORK is a string, it is the name to use for the new buffer." (defvar Info-read-node-completion-table) (defun Info-read-node-name-2 (dirs suffixes string pred action) - "Virtual completion table for file names input in Info node names." + "Internal function used to complete Info node names. +Return a completion table for Info files---the FILENAME part of a +node named \"(FILENAME)NODENAME\". DIRS is a list of Info +directories to search if FILENAME is not absolute; SUFFIXES is a +list of valid filename suffixes for Info files. See +`try-completion' for a description of the remaining arguments." (setq suffixes (remove "" suffixes)) (when (file-name-absolute-p string) (setq dirs (list (file-name-directory string)))) @@ -1602,10 +1633,9 @@ If FORK is a string, it is the name to use for the new buffer." (push (if string-dir (concat string-dir file) file) names))))) (complete-with-action action names string pred))) -;; This function is used as the "completion table" while reading a node name. -;; It does completion using the alist in Info-read-node-completion-table -;; unless STRING starts with an open-paren. (defun Info-read-node-name-1 (string predicate code) + "Internal function used by `Info-read-node-name'. +See `completing-read' for a description of arguments and usage." (cond ;; First complete embedded file names. ((string-match "\\`([^)]*\\'" string) @@ -1618,7 +1648,6 @@ If FORK is a string, it is the name to use for the new buffer." (substring string 1) predicate code)) - ;; If a file name was given, then any node is fair game. ((string-match "\\`(" string) (cond @@ -1630,9 +1659,10 @@ If FORK is a string, it is the name to use for the new buffer." code Info-read-node-completion-table string predicate)))) ;; Arrange to highlight the proper letters in the completion list buffer. - - (defun Info-read-node-name (prompt) + "Read an Info node name with completion, prompting with PROMPT. +A node name can have the form \"NODENAME\", referring to a node +in the current Info file, or \"(FILENAME)NODENAME\"." (let* ((completion-ignore-case t) (Info-read-node-completion-table (Info-build-node-completions)) (nodename (completing-read prompt 'Info-read-node-name-1 nil t))) @@ -1751,12 +1781,14 @@ 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 - (if (or (not isearch-mode) isearch-regexp) - Info-search-whitespace-regexp))) - (if backward - (re-search-backward regexp) - (re-search-forward regexp))) + (if isearch-mode + (signal 'search-failed (list regexp "end of manual")) + (let ((search-spaces-regexp + (if (or (not isearch-mode) isearch-regexp) + Info-search-whitespace-regexp))) + (if backward + (re-search-backward regexp) + (re-search-forward regexp)))) (setq found nil))) (if (and bound (not found)) @@ -1826,7 +1858,9 @@ If DIRECTION is `backward', search in the reverse direction." (setq list nil))) (if found (message "") - (signal 'search-failed (list regexp)))) + (signal 'search-failed (if isearch-mode + (list regexp "end of manual") + (list regexp))))) (if (not found) (progn (Info-read-subfile osubfile) (goto-char opoint) @@ -1984,8 +2018,8 @@ if ERRORNAME is nil, just return nil." (concat name ":" (Info-following-node-name-re)) bound t) (match-string-no-properties 1)) ((not (eq errorname t)) - (error "Node has no %s" - (capitalize (or errorname name))))))))) + (user-error "Node has no %s" + (capitalize (or errorname name))))))))) (defun Info-following-node-name-re (&optional allowedchars) "Return a regexp matching a node name. @@ -1995,7 +2029,7 @@ Submatch 1 is the complete node name. Submatch 2 if non-nil is the parenthesized file name part of the node name. Submatch 3 is the local part of the node name. End of submatch 0, 1, and 3 are the same, so you can safely concat." - (concat "[ \t]*" ;Skip leading space. + (concat "[ \t\n]*" ;Skip leading space. "\\(\\(([^)]+)\\)?" ;Node name can start with a file name. "\\([" (or allowedchars "^,\t\n") "]*" ;Any number of allowed chars. "[" (or allowedchars "^,\t\n") " ]" ;The last char can't be a space. @@ -2011,7 +2045,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) (pop-to-buffer "*info*")) + (or (eq major-mode 'Info-mode) (switch-to-buffer "*info*")) (Info-goto-node (Info-extract-pointer "next")))) (defun Info-prev () @@ -2019,7 +2053,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) (pop-to-buffer "*info*")) + (or (eq major-mode 'Info-mode) (switch-to-buffer "*info*")) (Info-goto-node (Info-extract-pointer "prev[ious]*" "previous")))) (defun Info-up (&optional same-file) @@ -2028,7 +2062,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) (pop-to-buffer "*info*")) + (or (eq major-mode 'Info-mode) (switch-to-buffer "*info*")) (let ((old-node Info-current-node) (old-file Info-current-file) (node (Info-extract-pointer "up")) p) @@ -2054,7 +2088,7 @@ If SAME-FILE is non-nil, do not move to a different Info file." "Go back in the history to the last node visited." (interactive) (or Info-history - (error "This is the first Info node you looked at")) + (user-error "This is the first Info node you looked at")) (let ((history-forward (cons (list Info-current-file Info-current-node (point)) Info-history-forward)) @@ -2074,7 +2108,7 @@ If SAME-FILE is non-nil, do not move to a different Info file." "Go forward in the history of visited nodes." (interactive) (or Info-history-forward - (error "This is the last Info node you looked at")) + (user-error "This is the last Info node you looked at")) (let ((history-forward (cdr Info-history-forward)) filename nodename opoint) (setq filename (car (car Info-history-forward))) @@ -2092,7 +2126,7 @@ If SAME-FILE is non-nil, do not move to a different Info file." )) (defun Info-directory-toc-nodes (filename) - "Directory-specific implementation of `Info-directory-toc-nodes'." + "Directory-specific implementation of `Info-toc-nodes'." `(,filename ("Top" nil nil nil))) @@ -2118,7 +2152,7 @@ If SAME-FILE is non-nil, do not move to a different Info file." )) (defun Info-history-toc-nodes (filename) - "History-specific implementation of `Info-history-toc-nodes'." + "History-specific implementation of `Info-toc-nodes'." `(,filename ("Top" nil nil nil))) @@ -2133,7 +2167,7 @@ If SAME-FILE is non-nil, do not move to a different Info file." (insert "Recently Visited Nodes\n") (insert "**********************\n\n") (insert "* Menu:\n\n") - (let ((hl (delete '("*History*" "Top") Info-history-list))) + (let ((hl (remove '("*History*" "Top") Info-history-list))) (while hl (let ((file (nth 0 (car hl))) (node (nth 1 (car hl)))) @@ -2229,7 +2263,7 @@ Table of contents is created from the tree structure of menus." (match-string-no-properties 1))) (section "Top") menu-items) - (when (string-match "(" upnode) (setq upnode nil)) + (when (and upnode (string-match "(" upnode)) (setq upnode nil)) (when (and (not (Info-index-node nodename file)) (re-search-forward "^\\* Menu:" bound t)) (forward-line 1) @@ -2360,7 +2394,7 @@ new buffer." completions nil t))) (list (if (equal input "") default input) current-prefix-arg)) - (error "No cross-references in this node")))) + (user-error "No cross-references in this node")))) (unless footnotename (error "No reference was specified")) @@ -2391,7 +2425,8 @@ new buffer." (abs (- prev-ref (point)))) next-ref prev-ref)) ((or next-ref prev-ref)) - ((error "No cross-reference named %s" footnotename)))) + ((user-error "No cross-reference named %s" + footnotename)))) (setq target (Info-extract-menu-node-name t)))) (while (setq i (string-match "[ \t\n]+" target i)) (setq target (concat (substring target 0 i) " " @@ -2430,7 +2465,8 @@ Because of ambiguities, this should be concatenated with something like ) (replace-regexp-in-string "[ \n]+" " " - (or (match-string-no-properties 2) + (or (and (not (equal (match-string-no-properties 2) "")) + (match-string-no-properties 2)) ;; If the node name is the menu entry name (using `entry::'). (buffer-substring-no-properties (match-beginning 0) (1- (match-beginning 1))))))) @@ -2535,7 +2571,7 @@ new buffer." (save-excursion (goto-char (point-min)) (if (not (search-forward "\n* menu:" nil t)) - (error "No menu in this node")) + (user-error "No menu in this node")) (setq beg (point)) (and (< (point) p) (save-excursion @@ -2565,7 +2601,9 @@ new buffer." (list item current-prefix-arg)))) ;; there is a problem here in that if several menu items have the same ;; name you can only go to the node of the first with this command. - (Info-goto-node (Info-extract-menu-item menu-item) (if fork menu-item))) + (Info-goto-node (Info-extract-menu-item menu-item) + (and fork + (if (stringp fork) fork menu-item)))) (defun Info-extract-menu-item (menu-item) (setq menu-item (regexp-quote menu-item)) @@ -2574,10 +2612,10 @@ new buffer." (let ((case-fold-search t)) (goto-char (point-min)) (or (search-forward "\n* menu:" nil t) - (error "No menu in this node")) + (user-error "No menu in this node")) (or (re-search-forward (concat "\n\\* +" menu-item ":") nil t) (re-search-forward (concat "\n\\* +" menu-item) nil t) - (error "No such item in menu")) + (user-error "No such item in menu")) (beginning-of-line) (forward-char 2) (Info-extract-menu-node-name nil (Info-index-node)))))) @@ -2593,7 +2631,7 @@ new buffer." (match-beginning 0)))) (goto-char (point-min)) (or (search-forward "\n* menu:" bound t) - (error "No menu in this node")) + (user-error "No menu in this node")) (if count (or (search-forward "\n* " bound t count) (error "Too few items in menu")) @@ -2657,12 +2695,15 @@ N is the digit argument used to invoke this command." "top"))) (let ((old-node Info-current-node)) (Info-up) - (let (Info-history success) + (let ((old-history Info-history) + success) (unwind-protect (setq success (Info-forward-node t nil no-error)) - (or success (Info-goto-node old-node)))))) + (or success (Info-goto-node old-node))) + (if Info-history-skip-intermediate-nodes + (setq Info-history old-history))))) (no-error nil) - (t (error "No pointer forward from this node"))))) + (t (user-error "No pointer forward from this node"))))) (defun Info-backward-node () "Go backward one node, considering all nodes as forming one sequence." @@ -2671,7 +2712,7 @@ N is the digit argument used to invoke this command." (upnode (Info-extract-pointer "up" t)) (case-fold-search t)) (cond ((and upnode (string-match "(" upnode)) - (error "First node in file")) + (user-error "First node in file")) ((and upnode (or (null prevnode) ;; Use string-equal, not equal, ;; to ignore text properties. @@ -2682,12 +2723,14 @@ N is the digit argument used to invoke this command." ;; If we move back at the same level, ;; go down to find the last subnode*. (Info-prev) - (let (Info-history) + (let ((old-history Info-history)) (while (and (not (Info-index-node)) (save-excursion (search-forward "\n* Menu:" nil t))) - (Info-goto-node (Info-extract-menu-counting nil))))) + (Info-goto-node (Info-extract-menu-counting nil))) + (if Info-history-skip-intermediate-nodes + (setq Info-history old-history)))) (t - (error "No pointer backward from this node"))))) + (user-error "No pointer backward from this node"))))) (defun Info-exit () "Exit Info by selecting some other buffer." @@ -2708,7 +2751,7 @@ N is the digit argument used to invoke this command." (and (search-forward "\n* " nil t) (Info-extract-menu-node-name))))) (if node (Info-goto-node node) - (error "No more items in menu")))) + (user-error "No more items in menu")))) (defun Info-last-menu-item () "Go to the node of the previous menu item." @@ -2721,7 +2764,7 @@ N is the digit argument used to invoke this command." (and (search-backward "\n* menu:" nil t) (point))))) (or (and beg (search-backward "\n* " beg t)) - (error "No previous items in menu"))) + (user-error "No previous items in menu"))) (Info-goto-node (save-excursion (goto-char (match-end 0)) (Info-extract-menu-node-name))))) @@ -2741,43 +2784,52 @@ N is the digit argument used to invoke this command." ;; Since logically we are done with the node with that menu, ;; move on from it. But don't add intermediate nodes ;; to the history on recursive calls. - (let (Info-history) - (Info-next-preorder))) + (let ((old-history Info-history)) + (Info-next-preorder) + (if Info-history-skip-intermediate-nodes + (setq Info-history old-history)))) (t - (error "No more nodes")))) + (user-error "No more nodes")))) (defun Info-last-preorder () "Go to the last node, popping up a level if there is none." (interactive) - (cond ((Info-no-error - (Info-last-menu-item) - ;; If we go down a menu item, go to the end of the node - ;; so we can scroll back through it. - (goto-char (point-max))) + (cond ((and Info-scroll-prefer-subnodes + (Info-no-error + (Info-last-menu-item) + ;; If we go down a menu item, go to the end of the node + ;; so we can scroll back through it. + (goto-char (point-max)))) ;; Keep going down, as long as there are nested menu nodes. - (while (Info-no-error - (Info-last-menu-item) - ;; If we go down a menu item, go to the end of the node - ;; so we can scroll back through it. - (goto-char (point-max)))) + (let ((old-history Info-history)) + (while (Info-no-error + (Info-last-menu-item) + ;; If we go down a menu item, go to the end of the node + ;; so we can scroll back through it. + (goto-char (point-max)))) + (if Info-history-skip-intermediate-nodes + (setq Info-history old-history))) (recenter -1)) ((and (Info-no-error (Info-extract-pointer "prev")) (not (equal (Info-extract-pointer "up") (Info-extract-pointer "prev")))) (Info-no-error (Info-prev)) (goto-char (point-max)) - (while (Info-no-error - (Info-last-menu-item) - ;; If we go down a menu item, go to the end of the node - ;; so we can scroll back through it. - (goto-char (point-max)))) + (let ((old-history Info-history)) + (while (Info-no-error + (Info-last-menu-item) + ;; If we go down a menu item, go to the end of the node + ;; so we can scroll back through it. + (goto-char (point-max)))) + (if Info-history-skip-intermediate-nodes + (setq Info-history old-history))) (recenter -1)) ((Info-no-error (Info-up t)) (goto-char (point-min)) (let ((case-fold-search t)) (or (search-forward "\n* Menu:" nil t) (goto-char (point-max))))) - (t (error "No previous nodes")))) + (t (user-error "No previous nodes")))) (defun Info-scroll-up () "Scroll one screenful forward in Info, considering all nodes as one sequence. @@ -2866,11 +2918,11 @@ See `Info-scroll-down'." (or (re-search-forward pat nil t) (progn (goto-char old-pt) - (error "No cross references in this node"))))) + (user-error "No cross references in this node"))))) (goto-char (or (match-beginning 1) (match-beginning 0))) (if (looking-at "\\* Menu:") (if recur - (error "No cross references in this node") + (user-error "No cross references in this node") (Info-next-reference t)) (if (looking-at "^\\* ") (forward-char 2))))) @@ -2887,11 +2939,11 @@ See `Info-scroll-down'." (or (re-search-backward pat nil t) (progn (goto-char old-pt) - (error "No cross references in this node"))))) + (user-error "No cross references in this node"))))) (goto-char (or (match-beginning 1) (match-beginning 0))) (if (looking-at "\\* Menu:") (if recur - (error "No cross references in this node") + (user-error "No cross references in this node") (Info-prev-reference t)) (if (looking-at "^\\* ") (forward-char 2))))) @@ -3062,7 +3114,7 @@ Give an empty topic name to go to the Index node itself." (or matches (progn (Info-goto-node orignode) - (error "No `%s' in index" topic))) + (user-error "No `%s' in index" topic))) ;; Here it is a feature that assoc is case-sensitive. (while (setq found (assoc topic matches)) (setq exact (cons found exact) @@ -3075,7 +3127,7 @@ Give an empty topic name to go to the Index node itself." "Go to the next matching index item from the last \\\\[Info-index] command." (interactive "p") (or Info-index-alternatives - (error "No previous `i' command")) + (user-error "No previous `i' command")) (while (< num 0) (setq num (+ num (length Info-index-alternatives)))) (while (> num 0) @@ -3205,7 +3257,7 @@ search results." (Info-index topic) (push (cons (cons Info-current-file topic) Info-index-alternatives) Info-virtual-index-nodes) - ;; Clean up unneccessary side-effects of `Info-index'. + ;; Clean up unnecessary side-effects of `Info-index'. (setq Info-history-list ohist-list) (Info-goto-node orignode) (message ""))) @@ -3230,7 +3282,7 @@ STRING is the search string given as an argument to `info-apropos', MATCHES is a list of index matches found by `Info-apropos-matches'.") (defun Info-apropos-toc-nodes (filename) - "Apropos-specific implementation of `Info-apropos-toc-nodes'." + "Apropos-specific implementation of `Info-toc-nodes'." (let ((nodes (mapcar 'car (reverse Info-apropos-nodes)))) `(,filename ("Top" nil nil ,nodes) @@ -3281,7 +3333,6 @@ MATCHES is a list of index matches found by `Info-apropos-matches'.") "Collect STRING matches from all known Info files on your system. Return a list of matches where each element is in the format \((FILENAME INDEXTEXT NODENAME LINENUMBER))." - (interactive "sIndex apropos: ") (unless (string= string "") (let ((pattern (format "\n\\* +\\([^\n]*%s[^\n]*\\):[ \t]+\\([^\n]+\\)\\.\\(?:[ \t\n]*(line +\\([0-9]+\\))\\)?" (regexp-quote string))) @@ -3294,7 +3345,7 @@ Return a list of matches where each element is in the format (Info-directory) ;; current-node and current-file are nil when they invoke info-apropos ;; as the first Info command, i.e. info-apropos loads info.el. In that - ;; case, we use (DIR)Top instead, to avoid signalling an error after + ;; case, we use (DIR)Top instead, to avoid signaling an error after ;; the search is complete. (when (null current-node) (setq current-file Info-current-file) @@ -3369,7 +3420,7 @@ Build a menu of the possible matches." (declare-function finder-unknown-keywords "finder" ()) (declare-function lm-commentary "lisp-mnt" (&optional file)) (defvar finder-keywords-hash) -(defvar package-alist) ; finder requires package +(defvar package--builtins) ; finder requires package (defun Info-finder-find-node (_filename nodename &optional _no-going-back) "Finder-specific implementation of `Info-find-node-2'." @@ -3383,14 +3434,14 @@ Build a menu of the possible matches." (insert "***************\n\n") (insert "* Menu:\n\n") (dolist (assoc (append '((all . "All package info") - (unknown . "unknown keywords")) + (unknown . "Unknown keywords")) finder-known-keywords)) (let ((keyword (car assoc))) (insert (format "* %s %s.\n" (concat (symbol-name keyword) ": " - "kw:" (symbol-name keyword) ".") + "Keyword " (symbol-name keyword) ".") (cdr assoc)))))) - ((equal nodename "unknown") + ((equal nodename "Keyword unknown") ;; Display unknown keywords (insert (format "\n\^_\nFile: %s, Node: %s, Up: Top\n\n" Info-finder-file nodename)) @@ -3400,24 +3451,29 @@ Build a menu of the possible matches." (mapc (lambda (assoc) (insert (format "* %-14s %s.\n" - (concat (symbol-name (car assoc)) "::") + (concat (symbol-name (car assoc)) ": " + "Keyword " (symbol-name (car assoc)) ".") (cdr assoc)))) (finder-unknown-keywords))) - ((equal nodename "all") + ((equal nodename "Keyword all") ;; Display all package info. (insert (format "\n\^_\nFile: %s, Node: %s, Up: Top\n\n" Info-finder-file nodename)) (insert "Finder Package Info\n") (insert "*******************\n\n") - (dolist (package package-alist) - (insert (format "%s - %s\n" - (format "*Note %s::" (nth 0 package)) - (nth 1 package))))) - ((string-match "\\`kw:" nodename) + (insert "* Menu:\n\n") + (let (desc) + (dolist (package package--builtins) + (setq desc (cdr-safe package)) + (when (vectorp desc) + (insert (format "* %-16s %s.\n" + (concat (symbol-name (car package)) "::") + (aref desc 2))))))) + ((string-match "\\`Keyword " nodename) (setq nodename (substring nodename (match-end 0))) ;; Display packages that match the keyword ;; or the list of keywords separated by comma. - (insert (format "\n\^_\nFile: %s, Node: kw:%s, Up: Top\n\n" + (insert (format "\n\^_\nFile: %s, Node: Keyword %s, Up: Top\n\n" Info-finder-file nodename)) (insert "Finder Packages\n") (insert "***************\n\n") @@ -3429,11 +3485,11 @@ Build a menu of the possible matches." (split-string nodename ",[ \t\n]*" t) (list nodename)))) hits desc) - (dolist (kw keywords) - (push (copy-tree (gethash kw finder-keywords-hash)) hits)) + (dolist (keyword keywords) + (push (copy-tree (gethash keyword finder-keywords-hash)) hits)) (setq hits (delete-dups (apply 'append hits))) (dolist (package hits) - (setq desc (cdr-safe (assq package package-alist))) + (setq desc (cdr-safe (assq package package--builtins))) (when (vectorp desc) (insert (format "* %-16s %s.\n" (concat (symbol-name package) "::") @@ -3591,7 +3647,7 @@ If FORK is a string, it is the name to use for the new buffer." ;; Don't raise an error when mouse-1 is bound to this - it's ;; often used to simply select the window or frame. (eq 'mouse-1 (event-basic-type last-input-event))) - (error "Point neither on reference nor in menu item description"))) + (user-error "Point neither on reference nor in menu item description"))) ;; Common subroutine. (defun Info-try-follow-nearest-node (&optional fork) @@ -3646,7 +3702,6 @@ If FORK is non-nil, it is passed to `Info-goto-node'." (define-key map "\C-m" 'Info-follow-nearest-node) (define-key map "\t" 'Info-next-reference) (define-key map "\e\t" 'Info-prev-reference) - (define-key map [(shift tab)] 'Info-prev-reference) (define-key map [backtab] 'Info-prev-reference) (define-key map "1" 'Info-nth-menu-item) (define-key map "2" 'Info-nth-menu-item) @@ -3664,8 +3719,9 @@ If FORK is non-nil, it is passed to `Info-goto-node'." (define-key map "<" 'Info-top-node) (define-key map ">" 'Info-final-node) (define-key map "b" 'beginning-of-buffer) + (put 'beginning-of-buffer :advertised-binding "b") (define-key map "d" 'Info-directory) - (define-key map "e" 'Info-edit) + (define-key map "e" 'end-of-buffer) (define-key map "f" 'Info-follow-reference) (define-key map "g" 'Info-goto-node) (define-key map "h" 'Info-help) @@ -3858,7 +3914,7 @@ The name of the Info file is prepended to the node name in parentheses. 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")) + (user-error "No current Info node")) (let ((node (if (stringp Info-current-file) (concat "(" (file-name-nondirectory Info-current-file) ") " Info-current-node)))) @@ -3878,6 +3934,14 @@ With a zero prefix arg, put the name inside a function call to `info'." (defvar tool-bar-map) (defvar bookmark-make-record-function) +(defvar Info-mode-syntax-table + (let ((st (copy-syntax-table text-mode-syntax-table))) + ;; Use punctuation syntax for apostrophe because of + ;; extensive use of quotes like `this' in Info manuals. + (modify-syntax-entry ?' "." st) + st) + "Syntax table used in `Info-mode'.") + ;; Autoload cookie needed by desktop.el ;;;###autoload (define-derived-mode Info-mode nil "Info" @@ -3942,7 +4006,7 @@ Advanced commands: \\[clone-buffer] Select a new cloned Info buffer in another window. \\[universal-argument] \\[info] Move to new Info file with completion. \\[universal-argument] N \\[info] Select Info buffer with prefix number in the name *info*." - :syntax-table text-mode-syntax-table + :syntax-table Info-mode-syntax-table :abbrev-table text-mode-abbrev-table (setq tab-width 8) (add-hook 'activate-menubar-hook 'Info-menu-update nil t) @@ -4766,7 +4830,7 @@ The INDENT level is ignored." (select-window bwin) (raise-frame (window-frame bwin))) (if speedbar-power-click - (let ((pop-up-frames t)) (select-window (display-buffer buff))) + (switch-to-buffer-other-frame buff) (speedbar-select-attached-frame) (switch-to-buffer buff))) (if (not (string-match "^(\\([^)]+\\))\\([^.]+\\)$" node)) @@ -4842,25 +4906,8 @@ BUFFER is the buffer speedbar is requesting buttons for." (erase-buffer)) (Info-speedbar-hierarchy-buttons nil 0)) -(dolist (mess '("^First node in file$" - "^No `.*' in index$" - "^No cross-reference named" - "^No cross.references in this node$" - "^No current Info node$" - "^No menu in this node$" - "^No more items in menu$" - "^No more nodes$" - "^No pointer \\(?:forward\\|backward\\) from this node$" - "^No previous `i' command$" - "^No previous items in menu$" - "^No previous nodes$" - "^No such item in menu$" - "^No such node or anchor" - "^Node has no" - "^Point neither on reference nor in menu item description$" - "^This is the \\(?:first\\|last\\) Info node you looked at$" - search-failed)) - (add-to-list 'debug-ignored-errors mess)) +;; FIXME: Really? Why here? +(add-to-list 'debug-ignored-errors 'search-failed) ;;;; Desktop support @@ -4945,7 +4992,7 @@ type returned by `Info-bookmark-make-record', which see." (setq found buffer blist nil)))) (if found - (pop-to-buffer found) + (switch-to-buffer found) (info-initialize) (info (Info-find-file manual)))))