Mercurial > emacs
comparison lisp/info.el @ 55751:450a4292b3b7
(Info-index-nodes): New var and fun.
(Info-goto-index, Info-index, info-apropos)
(Info-find-emacs-command-nodes): Rewrite to use Info-index-nodes.
(Info-index): Fix docstring. Store and restore Info-history-list.
(Info-complete-nodes): New var.
(Info-complete-menu-item): Use it.
(Info-index-node): New fun.
(Info-final-node, Info-forward-node, Info-backward-node)
(Info-build-toc, Info-try-follow-nearest-node, Info-fontify-node):
Use Info-index-node.
(Info-extract-menu-item, Info-extract-menu-counting): Set second
arg of `Info-extract-menu-node-name' to non-nil for index nodes.
(Info-find-node-2): If a node with period in its name not found,
try to find a node without the name part after period.
(Info-select-node): Call Info-fontify-node only if
Info-fontify-maximum-menu-size is not nil.
(info-apropos): Set Info-fontify-maximum-menu-size to nil.
(Info-find-emacs-command-nodes, Info-goto-emacs-command-node):
Preserve Info-history-list.
(Info-toc): Set Info-current-file.
(Info-build-toc): Move point to the beginning of the buffer.
Add main-file variable.
(Info-dir-remove-duplicates, Info-history, Info-toc, info-apropos):
Use backslashed representation of the control character ^_.
author | Juri Linkov <juri@jurta.org> |
---|---|
date | Sun, 23 May 2004 20:53:42 +0000 |
parents | 3616e8c83bfa |
children | 8926d01558fa |
comparison
equal
deleted
inserted
replaced
55750:3a482d346abb | 55751:450a4292b3b7 |
---|---|
861 ;; whether the node is right where we are, in case the | 861 ;; whether the node is right where we are, in case the |
862 ;; buffer begins with a node. | 862 ;; buffer begins with a node. |
863 (let ((pos (Info-find-node-in-buffer regexp))) | 863 (let ((pos (Info-find-node-in-buffer regexp))) |
864 (when pos | 864 (when pos |
865 (goto-char pos) | 865 (goto-char pos) |
866 (throw 'foo t)) | 866 (throw 'foo t))) |
867 ;; No such anchor in tag table or node in tag table or file | 867 |
868 (error "No such node or anchor: %s" nodename))) | 868 (when (string-match "\\([^.]+\\)\\." nodename) |
869 (let (Info-point-loc) | |
870 (Info-find-node-2 | |
871 filename (match-string 1 nodename) no-going-back)) | |
872 (widen) | |
873 (throw 'foo t)) | |
874 | |
875 ;; No such anchor in tag table or node in tag table or file | |
876 (error "No such node or anchor: %s" nodename)) | |
869 | 877 |
870 (Info-select-node) | 878 (Info-select-node) |
871 (goto-char (point-min)) | 879 (goto-char (point-min)) |
872 (cond (anchorpos | 880 (cond (anchorpos |
873 (let ((new-history (list Info-current-file | 881 (let ((new-history (list Info-current-file |
1073 (defun Info-dir-remove-duplicates () | 1081 (defun Info-dir-remove-duplicates () |
1074 (let (limit) | 1082 (let (limit) |
1075 (goto-char (point-min)) | 1083 (goto-char (point-min)) |
1076 ;; Remove duplicate headings in the same menu. | 1084 ;; Remove duplicate headings in the same menu. |
1077 (while (search-forward "\n* Menu:" nil t) | 1085 (while (search-forward "\n* Menu:" nil t) |
1078 (setq limit (save-excursion (search-forward "\n" nil t))) | 1086 (setq limit (save-excursion (search-forward "\n\^_" nil t))) |
1079 ;; Look for the next heading to unify. | 1087 ;; Look for the next heading to unify. |
1080 (while (re-search-forward "^\\(\\w.*\\)\n\\*" limit t) | 1088 (while (re-search-forward "^\\(\\w.*\\)\n\\*" limit t) |
1081 (let ((name (match-string 1)) | 1089 (let ((name (match-string 1)) |
1082 (start (match-beginning 0)) | 1090 (start (match-beginning 0)) |
1083 (entries nil) re) | 1091 (entries nil) re) |
1284 (if Info-enable-active-nodes (eval active-expression)) | 1292 (if Info-enable-active-nodes (eval active-expression)) |
1285 ;; Add a new unique history item to full history list | 1293 ;; Add a new unique history item to full history list |
1286 (let ((new-history (list Info-current-file Info-current-node))) | 1294 (let ((new-history (list Info-current-file Info-current-node))) |
1287 (setq Info-history-list | 1295 (setq Info-history-list |
1288 (cons new-history (delete new-history Info-history-list)))) | 1296 (cons new-history (delete new-history Info-history-list)))) |
1289 (Info-fontify-node) | 1297 (if (not (eq Info-fontify-maximum-menu-size nil)) |
1298 (Info-fontify-node)) | |
1290 (Info-display-images-node) | 1299 (Info-display-images-node) |
1291 (Info-hide-cookies-node) | 1300 (Info-hide-cookies-node) |
1292 (run-hooks 'Info-selection-hook))))) | 1301 (run-hooks 'Info-selection-hook))))) |
1293 | 1302 |
1294 (defun Info-set-mode-line () | 1303 (defun Info-set-mode-line () |
1644 p) | 1653 p) |
1645 (with-current-buffer (get-buffer-create " *info-history*") | 1654 (with-current-buffer (get-buffer-create " *info-history*") |
1646 (let ((inhibit-read-only t)) | 1655 (let ((inhibit-read-only t)) |
1647 (erase-buffer) | 1656 (erase-buffer) |
1648 (goto-char (point-min)) | 1657 (goto-char (point-min)) |
1649 (insert "\n\nFile: history Node: Top, Up: (dir)\n\n") | 1658 (insert "\n\^_\nFile: history Node: Top, Up: (dir)\n\n") |
1650 (insert "Recently Visited Nodes\n**********************\n\n") | 1659 (insert "Recently Visited Nodes\n**********************\n\n") |
1651 (insert "* Menu:\n\n") | 1660 (insert "* Menu:\n\n") |
1652 (let ((hl (delete '("history" "Top") Info-history-list))) | 1661 (let ((hl (delete '("history" "Top") Info-history-list))) |
1653 (while hl | 1662 (while hl |
1654 (let ((file (nth 0 (car hl))) | 1663 (let ((file (nth 0 (car hl))) |
1671 (with-current-buffer (get-buffer-create " *info-toc*") | 1680 (with-current-buffer (get-buffer-create " *info-toc*") |
1672 (let ((inhibit-read-only t) | 1681 (let ((inhibit-read-only t) |
1673 (node-list (Info-build-toc curr-file))) | 1682 (node-list (Info-build-toc curr-file))) |
1674 (erase-buffer) | 1683 (erase-buffer) |
1675 (goto-char (point-min)) | 1684 (goto-char (point-min)) |
1676 (insert "\n\nFile: toc Node: Top, Up: (dir)\n\n") | 1685 (insert "\n\^_\nFile: toc Node: Top, Up: (dir)\n\n") |
1677 (insert "Table of Contents\n*****************\n\n") | 1686 (insert "Table of Contents\n*****************\n\n") |
1678 (insert "*Note Top::\n") | 1687 (insert "*Note Top::\n") |
1679 (Info-insert-toc | 1688 (Info-insert-toc |
1680 (nth 2 (assoc "Top" node-list)) ; get Top nodes | 1689 (nth 2 (assoc "Top" node-list)) ; get Top nodes |
1681 node-list 0 curr-file)) | 1690 node-list 0 curr-file)) |
1682 (if (not (bobp)) | 1691 (if (not (bobp)) |
1683 (let ((Info-hide-note-references 'hide) | 1692 (let ((Info-hide-note-references 'hide) |
1684 (Info-fontify-visited-nodes nil)) | 1693 (Info-fontify-visited-nodes nil)) |
1685 (setq Info-current-node "Top") | 1694 (setq Info-current-file "toc" Info-current-node "Top") |
1686 (Info-fontify-node))) | 1695 (Info-fontify-node))) |
1687 (goto-char (point-min)) | 1696 (goto-char (point-min)) |
1688 (if (setq p (search-forward (concat "*Note " curr-node ":") nil t)) | 1697 (if (setq p (search-forward (concat "*Note " curr-node ":") nil t)) |
1689 (setq p (- p (length curr-node) 2)))) | 1698 (setq p (- p (length curr-node) 2)))) |
1690 (Info-find-node "toc" "Top") | 1699 (Info-find-node "toc" "Top") |
1705 (defun Info-build-toc (file) | 1714 (defun Info-build-toc (file) |
1706 "Build table of contents from menus of Info FILE and its subfiles." | 1715 "Build table of contents from menus of Info FILE and its subfiles." |
1707 (if (equal file "dir") | 1716 (if (equal file "dir") |
1708 (error "Table of contents for Info directory is not supported yet")) | 1717 (error "Table of contents for Info directory is not supported yet")) |
1709 (with-temp-buffer | 1718 (with-temp-buffer |
1710 (let ((default-directory (or (and (stringp file) | 1719 (let* ((default-directory (or (and (stringp file) |
1711 (file-name-directory | 1720 (file-name-directory |
1712 (setq file (Info-find-file file)))) | 1721 (setq file (Info-find-file file)))) |
1713 default-directory)) | 1722 default-directory)) |
1714 (sections '(("Top" "Top"))) | 1723 (main-file file) |
1715 nodes subfiles) | 1724 (sections '(("Top" "Top"))) |
1716 (while (or file subfiles) | 1725 nodes subfiles) |
1717 (or file (message "Searching subfile %s..." (car subfiles))) | 1726 (while (or main-file subfiles) |
1727 (or main-file (message "Searching subfile %s..." (car subfiles))) | |
1718 (erase-buffer) | 1728 (erase-buffer) |
1719 (info-insert-file-contents (or file (car subfiles))) | 1729 (info-insert-file-contents (or main-file (car subfiles))) |
1730 (goto-char (point-min)) | |
1720 (while (and (search-forward "\n\^_\nFile:" nil 'move) | 1731 (while (and (search-forward "\n\^_\nFile:" nil 'move) |
1721 (search-forward "Node: " nil 'move)) | 1732 (search-forward "Node: " nil 'move)) |
1722 (let ((nodename (substring-no-properties (Info-following-node-name))) | 1733 (let ((nodename (substring-no-properties (Info-following-node-name))) |
1723 (bound (- (or (save-excursion (search-forward "\n\^_" nil t)) | 1734 (bound (- (or (save-excursion (search-forward "\n\^_" nil t)) |
1724 (point-max)) 2)) | 1735 (point-max)) 2)) |
1725 (section "Top") | 1736 (section "Top") |
1726 menu-items) | 1737 menu-items) |
1727 (when (and (not (string-match "\\<index\\>" nodename)) | 1738 (when (and (not (Info-index-node nodename file)) |
1728 (re-search-forward "^\\* Menu:" bound t)) | 1739 (re-search-forward "^\\* Menu:" bound t)) |
1729 (forward-line 1) | 1740 (forward-line 1) |
1730 (beginning-of-line) | 1741 (beginning-of-line) |
1731 (setq bound (or (and (equal nodename "Top") | 1742 (setq bound (or (and (equal nodename "Top") |
1732 (save-excursion | 1743 (save-excursion |
1754 (setq nodes (cons (list nodename | 1765 (setq nodes (cons (list nodename |
1755 (cadr (assoc nodename sections)) | 1766 (cadr (assoc nodename sections)) |
1756 (nreverse menu-items)) | 1767 (nreverse menu-items)) |
1757 nodes)) | 1768 nodes)) |
1758 (goto-char bound))) | 1769 (goto-char bound))) |
1759 (if file | 1770 (if main-file |
1760 (save-excursion | 1771 (save-excursion |
1761 (goto-char (point-min)) | 1772 (goto-char (point-min)) |
1762 (if (search-forward "\n\^_\nIndirect:" nil t) | 1773 (if (search-forward "\n\^_\nIndirect:" nil t) |
1763 (let ((bound (save-excursion (search-forward "\n\^_" nil t)))) | 1774 (let ((bound (save-excursion (search-forward "\n\^_" nil t)))) |
1764 (while (re-search-forward "^\\(.*\\): [0-9]+$" bound t) | 1775 (while (re-search-forward "^\\(.*\\): [0-9]+$" bound t) |
1765 (setq subfiles (cons (match-string-no-properties 1) | 1776 (setq subfiles (cons (match-string-no-properties 1) |
1766 subfiles))))) | 1777 subfiles))))) |
1767 (setq subfiles (nreverse subfiles) | 1778 (setq subfiles (nreverse subfiles) |
1768 file nil)) | 1779 main-file nil)) |
1769 (setq subfiles (cdr subfiles)))) | 1780 (setq subfiles (cdr subfiles)))) |
1770 (message "") | 1781 (message "") |
1771 (nreverse nodes)))) | 1782 (nreverse nodes)))) |
1772 | 1783 |
1773 (defun Info-follow-reference (footnotename &optional fork) | 1784 (defun Info-follow-reference (footnotename &optional fork) |
1905 ;; (Info-menu (car list)) | 1916 ;; (Info-menu (car list)) |
1906 ;; (setq list (cdr list)))) | 1917 ;; (setq list (cdr list)))) |
1907 | 1918 |
1908 (defvar Info-complete-menu-buffer) | 1919 (defvar Info-complete-menu-buffer) |
1909 (defvar Info-complete-next-re nil) | 1920 (defvar Info-complete-next-re nil) |
1921 (defvar Info-complete-nodes nil) | |
1910 (defvar Info-complete-cache nil) | 1922 (defvar Info-complete-cache nil) |
1911 | 1923 |
1912 (defconst Info-node-spec-re | 1924 (defconst Info-node-spec-re |
1913 (concat (Info-following-node-name-re "^.,:") "[,:.]") | 1925 (concat (Info-following-node-name-re "^.,:") "[,:.]") |
1914 "Regexp to match the text after a : until the terminating `.'.") | 1926 "Regexp to match the text after a : until the terminating `.'.") |
1918 ;; - `Info-complete-menu-buffer' which contains the buffer in which | 1930 ;; - `Info-complete-menu-buffer' which contains the buffer in which |
1919 ;; is the menu of items we're trying to complete. | 1931 ;; is the menu of items we're trying to complete. |
1920 ;; - `Info-complete-next-re' which, if non-nil, indicates that we should | 1932 ;; - `Info-complete-next-re' which, if non-nil, indicates that we should |
1921 ;; also look for menu items in subsequent nodes as long as those | 1933 ;; also look for menu items in subsequent nodes as long as those |
1922 ;; nodes' names match `Info-complete-next-re'. This feature is currently | 1934 ;; nodes' names match `Info-complete-next-re'. This feature is currently |
1935 ;; not used. | |
1936 ;; - `Info-complete-nodes' which, if non-nil, indicates that we should | |
1937 ;; also look for menu items in these nodes. This feature is currently | |
1923 ;; only used for completion in Info-index. | 1938 ;; only used for completion in Info-index. |
1924 | 1939 |
1925 ;; Note that `Info-complete-menu-buffer' could be current already, | 1940 ;; Note that `Info-complete-menu-buffer' could be current already, |
1926 ;; so we want to save point. | 1941 ;; so we want to save point. |
1927 (save-excursion | 1942 (save-excursion |
1941 completions) | 1956 completions) |
1942 ;; Check the cache. | 1957 ;; Check the cache. |
1943 (if (and (equal (nth 0 Info-complete-cache) Info-current-file) | 1958 (if (and (equal (nth 0 Info-complete-cache) Info-current-file) |
1944 (equal (nth 1 Info-complete-cache) Info-current-node) | 1959 (equal (nth 1 Info-complete-cache) Info-current-node) |
1945 (equal (nth 2 Info-complete-cache) Info-complete-next-re) | 1960 (equal (nth 2 Info-complete-cache) Info-complete-next-re) |
1961 (equal (nth 5 Info-complete-cache) Info-complete-nodes) | |
1946 (let ((prev (nth 3 Info-complete-cache))) | 1962 (let ((prev (nth 3 Info-complete-cache))) |
1947 (eq t (compare-strings string 0 (length prev) | 1963 (eq t (compare-strings string 0 (length prev) |
1948 prev 0 nil t)))) | 1964 prev 0 nil t)))) |
1949 ;; We can reuse the previous list. | 1965 ;; We can reuse the previous list. |
1950 (setq completions (nth 4 Info-complete-cache)) | 1966 (setq completions (nth 4 Info-complete-cache)) |
1953 (progn | 1969 (progn |
1954 (while (re-search-forward pattern nil t) | 1970 (while (re-search-forward pattern nil t) |
1955 (push (match-string-no-properties 1) | 1971 (push (match-string-no-properties 1) |
1956 completions)) | 1972 completions)) |
1957 ;; Check subsequent nodes if applicable. | 1973 ;; Check subsequent nodes if applicable. |
1958 (and Info-complete-next-re | 1974 (or (and Info-complete-next-re |
1959 (setq nextnode (Info-extract-pointer "next" t)) | 1975 (setq nextnode (Info-extract-pointer "next" t)) |
1960 (string-match Info-complete-next-re nextnode))) | 1976 (string-match Info-complete-next-re nextnode)) |
1977 (and Info-complete-nodes | |
1978 (setq Info-complete-nodes (cdr Info-complete-nodes) | |
1979 nextnode (car Info-complete-nodes))))) | |
1961 (Info-goto-node nextnode)) | 1980 (Info-goto-node nextnode)) |
1962 ;; Go back to the start node (for the next completion). | 1981 ;; Go back to the start node (for the next completion). |
1963 (unless (equal Info-current-node orignode) | 1982 (unless (equal Info-current-node orignode) |
1964 (Info-goto-node orignode)) | 1983 (Info-goto-node orignode)) |
1965 ;; Update the cache. | 1984 ;; Update the cache. |
1966 (set (make-local-variable 'Info-complete-cache) | 1985 (set (make-local-variable 'Info-complete-cache) |
1967 (list Info-current-file Info-current-node | 1986 (list Info-current-file Info-current-node |
1968 Info-complete-next-re string completions))) | 1987 Info-complete-next-re string completions |
1988 Info-complete-nodes))) | |
1969 (if action | 1989 (if action |
1970 (all-completions string completions predicate) | 1990 (all-completions string completions predicate) |
1971 (try-completion string completions predicate))))))) | 1991 (try-completion string completions predicate))))))) |
1972 | 1992 |
1973 | 1993 |
2032 (or (re-search-forward (concat "\n\\* +" menu-item ":") nil t) | 2052 (or (re-search-forward (concat "\n\\* +" menu-item ":") nil t) |
2033 (re-search-forward (concat "\n\\* +" menu-item) nil t) | 2053 (re-search-forward (concat "\n\\* +" menu-item) nil t) |
2034 (error "No such item in menu")) | 2054 (error "No such item in menu")) |
2035 (beginning-of-line) | 2055 (beginning-of-line) |
2036 (forward-char 2) | 2056 (forward-char 2) |
2037 (Info-extract-menu-node-name))))) | 2057 (Info-extract-menu-node-name nil (Info-index-node)))))) |
2038 | 2058 |
2039 ;; If COUNT is nil, use the last item in the menu. | 2059 ;; If COUNT is nil, use the last item in the menu. |
2040 (defun Info-extract-menu-counting (count) | 2060 (defun Info-extract-menu-counting (count) |
2041 (let ((case-fold-search t)) | 2061 (let ((case-fold-search t)) |
2042 (save-excursion | 2062 (save-excursion |
2047 (if count | 2067 (if count |
2048 (or (search-forward "\n* " nil t count) | 2068 (or (search-forward "\n* " nil t count) |
2049 (error "Too few items in menu")) | 2069 (error "Too few items in menu")) |
2050 (while (search-forward "\n* " nil t) | 2070 (while (search-forward "\n* " nil t) |
2051 nil)) | 2071 nil)) |
2052 (Info-extract-menu-node-name))))) | 2072 (Info-extract-menu-node-name nil (Info-index-node)))))) |
2053 | 2073 |
2054 (defun Info-nth-menu-item () | 2074 (defun Info-nth-menu-item () |
2055 "Go to the node of the Nth menu item. | 2075 "Go to the node of the Nth menu item. |
2056 N is the digit argument used to invoke this command." | 2076 N is the digit argument used to invoke this command." |
2057 (interactive) | 2077 (interactive) |
2074 (Info-goto-node (Info-extract-menu-counting nil)) | 2094 (Info-goto-node (Info-extract-menu-counting nil)) |
2075 ;; If the last node in the menu is not last in pointer structure, | 2095 ;; If the last node in the menu is not last in pointer structure, |
2076 ;; move forward until we can't go any farther. | 2096 ;; move forward until we can't go any farther. |
2077 (while (Info-forward-node t t) nil) | 2097 (while (Info-forward-node t t) nil) |
2078 ;; Then keep moving down to last subnode, unless we reach an index. | 2098 ;; Then keep moving down to last subnode, unless we reach an index. |
2079 (while (and (not (string-match "\\<index\\>" Info-current-node)) | 2099 (while (and (not (Info-index-node)) |
2080 (save-excursion (search-forward "\n* Menu:" nil t))) | 2100 (save-excursion (search-forward "\n* Menu:" nil t))) |
2081 (Info-goto-node (Info-extract-menu-counting nil))))) | 2101 (Info-goto-node (Info-extract-menu-counting nil))))) |
2082 | 2102 |
2083 (defun Info-forward-node (&optional not-down no-error) | 2103 (defun Info-forward-node (&optional not-down no-error) |
2084 "Go forward one node, considering all nodes as forming one sequence." | 2104 "Go forward one node, considering all nodes as forming one sequence." |
2090 ;; 1. next node is in a menu in this node (but not in an index) | 2110 ;; 1. next node is in a menu in this node (but not in an index) |
2091 ;; 2. next node is next at same level | 2111 ;; 2. next node is next at same level |
2092 ;; 3. next node is up and next | 2112 ;; 3. next node is up and next |
2093 (cond ((and (not not-down) | 2113 (cond ((and (not not-down) |
2094 (save-excursion (search-forward "\n* menu:" nil t)) | 2114 (save-excursion (search-forward "\n* menu:" nil t)) |
2095 (not (string-match "\\<index\\>" Info-current-node))) | 2115 (not (Info-index-node))) |
2096 (Info-goto-node (Info-extract-menu-counting 1)) | 2116 (Info-goto-node (Info-extract-menu-counting 1)) |
2097 t) | 2117 t) |
2098 ((save-excursion (search-backward "next:" nil t)) | 2118 ((save-excursion (search-backward "next:" nil t)) |
2099 (Info-next) | 2119 (Info-next) |
2100 t) | 2120 t) |
2128 (prevnode | 2148 (prevnode |
2129 ;; If we move back at the same level, | 2149 ;; If we move back at the same level, |
2130 ;; go down to find the last subnode*. | 2150 ;; go down to find the last subnode*. |
2131 (Info-prev) | 2151 (Info-prev) |
2132 (let (Info-history) | 2152 (let (Info-history) |
2133 (while (and (not (string-match "\\<index\\>" Info-current-node)) | 2153 (while (and (not (Info-index-node)) |
2134 (save-excursion (search-forward "\n* Menu:" nil t))) | 2154 (save-excursion (search-forward "\n* Menu:" nil t))) |
2135 (Info-goto-node (Info-extract-menu-counting nil))))) | 2155 (Info-goto-node (Info-extract-menu-counting nil))))) |
2136 (t | 2156 (t |
2137 (error "No pointer backward from this node"))))) | 2157 (error "No pointer backward from this node"))))) |
2138 | 2158 |
2319 (goto-char (or (match-beginning 1) (match-beginning 0))) | 2339 (goto-char (or (match-beginning 1) (match-beginning 0))) |
2320 (if (looking-at "\\* Menu:") | 2340 (if (looking-at "\\* Menu:") |
2321 (if recur | 2341 (if recur |
2322 (error "No cross references in this node") | 2342 (error "No cross references in this node") |
2323 (Info-prev-reference t))))) | 2343 (Info-prev-reference t))))) |
2344 | |
2345 (defvar Info-index-nodes nil | |
2346 "Alist of cached index node names of visited Info files. | |
2347 Each element has the form (INFO-FILE INDEX-NODE-NAMES-LIST).") | |
2348 | |
2349 (defun Info-index-nodes (&optional file) | |
2350 "Return a list of names of all index nodes in Info FILE. | |
2351 If FILE is omitted, it defaults to the current Info file. | |
2352 First look in a list of cached index node names. Then scan Info file | |
2353 and its subfiles for nodes with index cookie. Then try index nodes | |
2354 starting from the first node in the top level menu whose name | |
2355 contains the word \"Index\", plus any immediately following nodes | |
2356 whose names also contain the word \"Index\"." | |
2357 (or file (setq file Info-current-file)) | |
2358 (or (assoc file Info-index-nodes) | |
2359 ;; Skip virtual Info files | |
2360 (member file '("dir" "history" "toc" "apropos")) | |
2361 ;; Find nodes with index cookie | |
2362 (let* ((default-directory (or (and (stringp file) | |
2363 (file-name-directory | |
2364 (setq file (Info-find-file file)))) | |
2365 default-directory)) | |
2366 (main-file file) | |
2367 (Info-fontify-maximum-menu-size nil) | |
2368 subfiles nodes node Info-history Info-history-list) | |
2369 (with-temp-buffer | |
2370 (while (or main-file subfiles) | |
2371 (erase-buffer) | |
2372 (info-insert-file-contents (or main-file (car subfiles))) | |
2373 (goto-char (point-min)) | |
2374 (while (search-forward "\0\10[index\0\10]" nil 'move) | |
2375 (save-excursion | |
2376 (re-search-backward "^\^_") | |
2377 (search-forward "Node: ") | |
2378 (setq nodes (cons (Info-following-node-name) nodes)))) | |
2379 (if main-file | |
2380 (save-excursion | |
2381 (goto-char (point-min)) | |
2382 (if (search-forward "\n\^_\nIndirect:" nil t) | |
2383 (let ((bound (save-excursion (search-forward "\n\^_" nil t)))) | |
2384 (while (re-search-forward "^\\(.*\\): [0-9]+$" bound t) | |
2385 (setq subfiles (cons (match-string-no-properties 1) | |
2386 subfiles))))) | |
2387 (setq subfiles (nreverse subfiles) | |
2388 main-file nil)) | |
2389 (setq subfiles (cdr subfiles))))) | |
2390 (if nodes | |
2391 (setq nodes (nreverse nodes) | |
2392 Info-index-nodes (cons (cons file nodes) Info-index-nodes))) | |
2393 nodes) | |
2394 ;; Find nodes with string "Index" in node names | |
2395 (let ((Info-fontify-maximum-menu-size nil) | |
2396 (case-fold-search t) | |
2397 nodes node Info-history Info-history-list) | |
2398 (with-temp-buffer | |
2399 (Info-mode) | |
2400 (Info-find-node file "Top") | |
2401 (when (and (search-forward "\n* menu:" nil t) | |
2402 (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t)) | |
2403 (goto-char (match-beginning 1)) | |
2404 (setq nodes (list (Info-extract-menu-node-name))) | |
2405 (Info-goto-node (car nodes)) | |
2406 (while (and (setq node (Info-extract-pointer "next" t)) | |
2407 (string-match "\\<Index\\>" node)) | |
2408 (setq nodes (cons node nodes)) | |
2409 (Info-goto-node node)))) | |
2410 (if nodes | |
2411 (setq nodes (nreverse nodes) | |
2412 Info-index-nodes (cons (cons file nodes) Info-index-nodes))) | |
2413 nodes) | |
2414 ;; Info file has no index nodes | |
2415 (setq Info-index-nodes (cons (cons file nil) | |
2416 Info-index-nodes))) | |
2417 (cdr (assoc file Info-index-nodes))) | |
2418 | |
2419 (defun Info-index-node (&optional node file) | |
2420 "Return non-nil value if NODE is an index node. | |
2421 If NODE is nil, check the current Info node. | |
2422 If FILE is nil, check the current Info file." | |
2423 (member (or node Info-current-node) (Info-index-nodes file))) | |
2324 | 2424 |
2325 (defun Info-goto-index () | 2425 (defun Info-goto-index () |
2326 (Info-goto-node "Top") | 2426 "Go to the first index node." |
2327 (or (search-forward "\n* menu:" nil t) | 2427 (let ((node (car (Info-index-nodes)))) |
2328 (error "No index")) | 2428 (or node (error "No index")) |
2329 (or (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t) | 2429 (Info-goto-node node))) |
2330 (error "No index")) | |
2331 (goto-char (match-beginning 1)) | |
2332 ;; Protect Info-history so that the current node (Top) is not added to it. | |
2333 (let ((Info-history nil)) | |
2334 (Info-goto-node (Info-extract-menu-node-name)))) | |
2335 | 2430 |
2336 ;;;###autoload | 2431 ;;;###autoload |
2337 (defun Info-index (topic) | 2432 (defun Info-index (topic) |
2338 "Look up a string TOPIC in the index for this file. | 2433 "Look up a string TOPIC in the index for this file. |
2339 The index is defined as the first node in the top level menu whose | |
2340 name contains the word \"Index\", plus any immediately following | |
2341 nodes whose names also contain the word \"Index\". | |
2342 If there are no exact matches to the specified topic, this chooses | 2434 If there are no exact matches to the specified topic, this chooses |
2343 the first match which is a case-insensitive substring of a topic. | 2435 the first match which is a case-insensitive substring of a topic. |
2344 Use the \\<Info-mode-map>\\[Info-index-next] command to see the other matches. | 2436 Use the \\<Info-mode-map>\\[Info-index-next] command to see the other matches. |
2345 Give a blank topic name to go to the Index node itself." | 2437 Give a blank topic name to go to the Index node itself." |
2346 (interactive | 2438 (interactive |
2347 (list | 2439 (list |
2348 (let ((Info-complete-menu-buffer (clone-buffer)) | 2440 (let ((Info-complete-menu-buffer (clone-buffer)) |
2349 (Info-complete-next-re "\\<Index\\>")) | 2441 (Info-complete-nodes (Info-index-nodes)) |
2442 (Info-history-list nil)) | |
2350 (if (equal Info-current-file "dir") | 2443 (if (equal Info-current-file "dir") |
2351 (error "The Info directory node has no index; use m to select a manual")) | 2444 (error "The Info directory node has no index; use m to select a manual")) |
2352 (unwind-protect | 2445 (unwind-protect |
2353 (with-current-buffer Info-complete-menu-buffer | 2446 (with-current-buffer Info-complete-menu-buffer |
2354 (Info-goto-index) | 2447 (Info-goto-index) |
2357 (if (equal Info-current-file "dir") | 2450 (if (equal Info-current-file "dir") |
2358 (error "The Info directory node has no index; use m to select a manual")) | 2451 (error "The Info directory node has no index; use m to select a manual")) |
2359 (let ((orignode Info-current-node) | 2452 (let ((orignode Info-current-node) |
2360 (pattern (format "\n\\* +\\([^\n]*%s[^\n]*\\):[ \t]+\\([^\n]*\\)\\.\\(?:[ \t\n]*(line +\\([0-9]+\\))\\)?" | 2453 (pattern (format "\n\\* +\\([^\n]*%s[^\n]*\\):[ \t]+\\([^\n]*\\)\\.\\(?:[ \t\n]*(line +\\([0-9]+\\))\\)?" |
2361 (regexp-quote topic))) | 2454 (regexp-quote topic))) |
2362 node | 2455 node (nodes (Info-index-nodes)) |
2456 (ohist-list Info-history-list) | |
2363 (case-fold-search t)) | 2457 (case-fold-search t)) |
2364 (Info-goto-index) | 2458 (Info-goto-index) |
2365 (or (equal topic "") | 2459 (or (equal topic "") |
2366 (let ((matches nil) | 2460 (let ((matches nil) |
2367 (exact nil) | 2461 (exact nil) |
2379 (match-string-no-properties 2) | 2473 (match-string-no-properties 2) |
2380 Info-current-node | 2474 Info-current-node |
2381 (string-to-number (concat "0" | 2475 (string-to-number (concat "0" |
2382 (match-string 3)))) | 2476 (match-string 3)))) |
2383 matches)) | 2477 matches)) |
2384 (and (setq node (Info-extract-pointer "next" t)) | 2478 (setq nodes (cdr nodes) node (car nodes))) |
2385 (string-match "\\<Index\\>" node))) | |
2386 (Info-goto-node node)) | 2479 (Info-goto-node node)) |
2387 (or matches | 2480 (or matches |
2388 (progn | 2481 (progn |
2389 (Info-goto-node orignode) | 2482 (Info-goto-node orignode) |
2390 (error "No `%s' in index" topic))) | 2483 (error "No `%s' in index" topic))) |
2391 ;; Here it is a feature that assoc is case-sensitive. | 2484 ;; Here it is a feature that assoc is case-sensitive. |
2392 (while (setq found (assoc topic matches)) | 2485 (while (setq found (assoc topic matches)) |
2393 (setq exact (cons found exact) | 2486 (setq exact (cons found exact) |
2394 matches (delq found matches))) | 2487 matches (delq found matches))) |
2488 (setq Info-history-list ohist-list) | |
2395 (setq Info-index-alternatives (nconc exact (nreverse matches))) | 2489 (setq Info-index-alternatives (nconc exact (nreverse matches))) |
2396 (Info-index-next 0))))) | 2490 (Info-index-next 0))))) |
2397 | 2491 |
2398 (defun Info-index-next (num) | 2492 (defun Info-index-next (num) |
2399 "Go to the next matching index item from the last \\<Info-mode-map>\\[Info-index] command." | 2493 "Go to the next matching index item from the last \\<Info-mode-map>\\[Info-index] command." |
2452 (regexp-quote string))) | 2546 (regexp-quote string))) |
2453 (ohist Info-history) | 2547 (ohist Info-history) |
2454 (ohist-list Info-history-list) | 2548 (ohist-list Info-history-list) |
2455 (current-node Info-current-node) | 2549 (current-node Info-current-node) |
2456 (current-file Info-current-file) | 2550 (current-file Info-current-file) |
2457 manuals matches node) | 2551 manuals matches node nodes) |
2458 (let ((Info-fontify-maximum-menu-size 0) | 2552 (let ((Info-fontify-maximum-menu-size nil)) |
2459 Info-use-header-lines | |
2460 Info-hide-note-references) | |
2461 (Info-directory) | 2553 (Info-directory) |
2462 (message "Searching indices...") | 2554 (message "Searching indices...") |
2463 (goto-char (point-min)) | 2555 (goto-char (point-min)) |
2464 (re-search-forward "\\* Menu: *\n" nil t) | 2556 (re-search-forward "\\* Menu: *\n" nil t) |
2465 (while (re-search-forward "\\*.*: *(\\([^)]+\\))" nil t) | 2557 (while (re-search-forward "\\*.*: *(\\([^)]+\\))" nil t) |
2466 (add-to-list 'manuals (match-string 1))) | 2558 (add-to-list 'manuals (match-string 1))) |
2467 (dolist (manual manuals) | 2559 (dolist (manual manuals) |
2468 (message "Searching %s" manual) | 2560 (message "Searching %s" manual) |
2469 (condition-case nil | 2561 (if (setq nodes (Info-index-nodes (Info-find-file manual))) |
2470 (save-excursion | 2562 (condition-case nil |
2471 (Info-find-node manual "Top") | 2563 (save-excursion |
2472 (when (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t) | 2564 (Info-find-node manual (car nodes)) |
2473 (goto-char (match-beginning 1)) | 2565 (while |
2474 (Info-goto-node (Info-extract-menu-node-name)) | 2566 (progn |
2475 (while | 2567 (goto-char (point-min)) |
2476 (progn | 2568 (while (re-search-forward pattern nil t) |
2477 (goto-char (point-min)) | 2569 (add-to-list 'matches |
2478 (while (re-search-forward pattern nil t) | 2570 (list manual |
2479 (add-to-list 'matches | 2571 (match-string-no-properties 1) |
2480 (list manual | 2572 (match-string-no-properties 2) |
2481 (match-string-no-properties 1) | 2573 (match-string-no-properties 3)))) |
2482 (match-string-no-properties 2) | 2574 (setq nodes (cdr nodes) node (car nodes))) |
2483 (match-string-no-properties 3)))) | 2575 (Info-goto-node node))) |
2484 (and (setq node (Info-extract-pointer "next" t)) | 2576 (error nil))))) |
2485 (string-match "\\<Index\\>" node))) | |
2486 (Info-goto-node node)))) | |
2487 (error nil)))) | |
2488 (Info-goto-node (concat "(" current-file ")" current-node)) | 2577 (Info-goto-node (concat "(" current-file ")" current-node)) |
2489 (setq Info-history ohist | 2578 (setq Info-history ohist |
2490 Info-history-list ohist-list) | 2579 Info-history-list ohist-list) |
2491 (message "Searching indices...done") | 2580 (message "Searching indices...done") |
2492 (if (null matches) | 2581 (if (null matches) |
2493 (message "No matches found") | 2582 (message "No matches found") |
2494 (with-current-buffer (get-buffer-create " *info-apropos*") | 2583 (with-current-buffer (get-buffer-create " *info-apropos*") |
2495 (erase-buffer) | 2584 (erase-buffer) |
2496 (insert "\n\nFile: apropos, Node: Index, Up: (dir)\n") | 2585 (insert "\n\^_\nFile: apropos, Node: Index, Up: (dir)\n") |
2497 (insert "* Menu: \nNodes whose indices contain \"" string "\"\n\n") | 2586 (insert "* Menu: \nNodes whose indices contain \"" string "\"\n\n") |
2498 (dolist (entry matches) | 2587 (dolist (entry matches) |
2499 (insert | 2588 (insert |
2500 (format "* %-38s (%s)%s.%s\n" | 2589 (format "* %-38s (%s)%s.%s\n" |
2501 (concat (nth 1 entry) " [" (nth 0 entry) "]:") | 2590 (concat (nth 1 entry) " [" (nth 0 entry) "]:") |
2627 (Info-goto-node node fork)) | 2716 (Info-goto-node node fork)) |
2628 ;; menu item: node name or index entry | 2717 ;; menu item: node name or index entry |
2629 ((Info-get-token (point) "\\* +" "\\* +\\(.*\\): ") | 2718 ((Info-get-token (point) "\\* +" "\\* +\\(.*\\): ") |
2630 (beginning-of-line) | 2719 (beginning-of-line) |
2631 (forward-char 2) | 2720 (forward-char 2) |
2632 (setq node (Info-extract-menu-node-name | 2721 (setq node (Info-extract-menu-node-name nil (Info-index-node))) |
2633 nil (string-match "\\<index\\>" Info-current-node))) | |
2634 (Info-goto-node node fork)) | 2722 (Info-goto-node node fork)) |
2635 ((setq node (Info-get-token (point) "Up: " "Up: \\([^,\n\t]*\\)")) | 2723 ((setq node (Info-get-token (point) "Up: " "Up: \\([^,\n\t]*\\)")) |
2636 (Info-goto-node node fork)) | 2724 (Info-goto-node node fork)) |
2637 ((setq node (Info-get-token (point) "Next: " "Next: \\([^,\n\t]*\\)")) | 2725 ((setq node (Info-get-token (point) "Next: " "Next: \\([^,\n\t]*\\)")) |
2638 (Info-goto-node node fork)) | 2726 (Info-goto-node node fork)) |
3070 (error "Info file `%s' appears to lack an index" info-file)) | 3158 (error "Info file `%s' appears to lack an index" info-file)) |
3071 (goto-char (match-beginning 1)) | 3159 (goto-char (match-beginning 1)) |
3072 ;; Bind Info-history to nil, to prevent the index nodes from | 3160 ;; Bind Info-history to nil, to prevent the index nodes from |
3073 ;; getting into the node history. | 3161 ;; getting into the node history. |
3074 (let ((Info-history nil) | 3162 (let ((Info-history nil) |
3075 node) | 3163 (Info-history-list nil) |
3076 (Info-goto-node (Info-extract-menu-node-name)) | 3164 node (nodes (Info-index-nodes))) |
3165 (Info-goto-node (car nodes)) | |
3077 (while | 3166 (while |
3078 (progn | 3167 (progn |
3079 (goto-char (point-min)) | 3168 (goto-char (point-min)) |
3080 (while (re-search-forward cmd-desc nil t) | 3169 (while (re-search-forward cmd-desc nil t) |
3081 (setq where | 3170 (setq where |
3082 (cons (list Info-current-file | 3171 (cons (list Info-current-file |
3083 (match-string-no-properties 2) | 3172 (match-string-no-properties 2) |
3084 0) | 3173 0) |
3085 where))) | 3174 where))) |
3086 (and (setq node (Info-extract-pointer "next" t)) | 3175 (and (setq nodes (cdr nodes) node (car nodes)))) |
3087 (string-match "\\<Index\\>" node))) | |
3088 (Info-goto-node node))) | 3176 (Info-goto-node node))) |
3089 where)) | 3177 where)) |
3090 | 3178 |
3091 ;;;###autoload | 3179 ;;;###autoload |
3092 (defun Info-goto-emacs-command-node (command) | 3180 (defun Info-goto-emacs-command-node (command) |
3109 (info)) | 3197 (info)) |
3110 (or (eq major-mode 'Info-mode) (pop-to-buffer "*info*")) | 3198 (or (eq major-mode 'Info-mode) (pop-to-buffer "*info*")) |
3111 ;; Bind Info-history to nil, to prevent the last Index node | 3199 ;; Bind Info-history to nil, to prevent the last Index node |
3112 ;; visited by Info-find-emacs-command-nodes from being | 3200 ;; visited by Info-find-emacs-command-nodes from being |
3113 ;; pushed onto the history. | 3201 ;; pushed onto the history. |
3114 (let ((Info-history nil)) | 3202 (let ((Info-history nil) (Info-history-list nil)) |
3115 (Info-find-node (car (car where)) | 3203 (Info-find-node (car (car where)) |
3116 (car (cdr (car where))))) | 3204 (car (cdr (car where))))) |
3117 (if (> num-matches 1) | 3205 (if (> num-matches 1) |
3118 (progn | 3206 (progn |
3119 ;; (car where) will be pushed onto Info-history | 3207 ;; (car where) will be pushed onto Info-history |
3446 | 3534 |
3447 ;; Fontify menu items | 3535 ;; Fontify menu items |
3448 (goto-char (point-min)) | 3536 (goto-char (point-min)) |
3449 (when (and (or not-fontified-p fontify-visited-p) | 3537 (when (and (or not-fontified-p fontify-visited-p) |
3450 (search-forward "\n* Menu:" nil t) | 3538 (search-forward "\n* Menu:" nil t) |
3451 (not (string-match "\\<Index\\>" Info-current-node)) | 3539 (not (Info-index-node)) |
3452 ;; Don't take time to annotate huge menus | 3540 ;; Don't take time to annotate huge menus |
3453 (< (- (point-max) (point)) Info-fontify-maximum-menu-size)) | 3541 (< (- (point-max) (point)) Info-fontify-maximum-menu-size)) |
3454 (let ((n 0) | 3542 (let ((n 0) |
3455 cont) | 3543 cont) |
3456 (while (re-search-forward | 3544 (while (re-search-forward |
3535 (put-text-property (match-beginning 1) (match-end 1) | 3623 (put-text-property (match-beginning 1) (match-end 1) |
3536 'font-lock-face 'info-menu-header))) | 3624 'font-lock-face 'info-menu-header))) |
3537 | 3625 |
3538 ;; Hide index line numbers | 3626 ;; Hide index line numbers |
3539 (goto-char (point-min)) | 3627 (goto-char (point-min)) |
3540 (when (and not-fontified-p (string-match "\\<Index\\>" Info-current-node)) | 3628 (when (and not-fontified-p (Info-index-node)) |
3541 (while (re-search-forward "[ \t\n]*(line +[0-9]+)" nil t) | 3629 (while (re-search-forward "[ \t\n]*(line +[0-9]+)" nil t) |
3542 (put-text-property (match-beginning 0) (match-end 0) | 3630 (put-text-property (match-beginning 0) (match-end 0) |
3543 'invisible t))) | 3631 'invisible t))) |
3544 | 3632 |
3545 ;; Fontify http and ftp references | 3633 ;; Fontify http and ftp references |