diff options
| author | Stefan Monnier | 2001-11-29 23:20:49 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2001-11-29 23:20:49 +0000 |
| commit | e4e8ee638ec1500f33a546b892cd78a1988ee36f (patch) | |
| tree | b45a5b8c6d899750feffa992f220c7606df272c3 | |
| parent | 75e95a9780cde9a02a20b4e42b7328ddc13e6a89 (diff) | |
| download | emacs-e4e8ee638ec1500f33a546b892cd78a1988ee36f.tar.gz emacs-e4e8ee638ec1500f33a546b892cd78a1988ee36f.zip | |
(Info-complete-next-re, Info-complete-cache): New vars.
(Info-complete-menu-item): Rewrite. Add the ability to search
several sequential nodes. Add a simple caching mechanism.
(Info-goto-index): New function extracted from Info-index.
(Info-index): Use it. Add completion to the interactive spec.
(Info-menu-update): Simplify call to `Info-complete-menu-item'.
| -rw-r--r-- | lisp/info.el | 121 |
1 files changed, 69 insertions, 52 deletions
diff --git a/lisp/info.el b/lisp/info.el index 58e1b0b9f89..1c6242375de 100644 --- a/lisp/info.el +++ b/lisp/info.el | |||
| @@ -1407,49 +1407,56 @@ FOOTNOTENAME may be an abbreviation of the reference name." | |||
| 1407 | ;; (setq list (cdr list)))) | 1407 | ;; (setq list (cdr list)))) |
| 1408 | 1408 | ||
| 1409 | (defvar Info-complete-menu-buffer) | 1409 | (defvar Info-complete-menu-buffer) |
| 1410 | (defvar Info-complete-next-re nil) | ||
| 1411 | (defvar Info-complete-cache nil) | ||
| 1410 | 1412 | ||
| 1411 | (defun Info-complete-menu-item (string predicate action) | 1413 | (defun Info-complete-menu-item (string predicate action) |
| 1412 | (let ((completion-ignore-case t) | 1414 | (save-excursion |
| 1413 | (case-fold-search t)) | 1415 | (set-buffer Info-complete-menu-buffer) |
| 1414 | (cond ((eq action nil) | 1416 | (let ((completion-ignore-case t) |
| 1415 | (let (completions | 1417 | (case-fold-search t) |
| 1416 | (pattern (concat "\n\\* +\\(" | 1418 | (orignode Info-current-node) |
| 1417 | (regexp-quote string) | 1419 | nextnode) |
| 1418 | "[^:\t\n]*\\):"))) | 1420 | (goto-char (point-min)) |
| 1419 | (save-excursion | 1421 | (search-forward "\n* Menu:") |
| 1420 | (set-buffer Info-complete-menu-buffer) | 1422 | (if (not (memq action '(nil t))) |
| 1421 | (goto-char (point-min)) | 1423 | (re-search-forward |
| 1422 | (search-forward "\n* Menu:") | 1424 | (concat "\n\\* +" (regexp-quote string) ":") nil t) |
| 1423 | (while (re-search-forward pattern nil t) | 1425 | (let ((pattern (concat "\n\\* +\\(" |
| 1424 | (setq completions | 1426 | (regexp-quote string) |
| 1425 | (cons (cons (match-string-no-properties 1) | 1427 | "[^:\t\n]*\\):")) |
| 1426 | (match-beginning 1)) | 1428 | completions) |
| 1427 | completions)))) | 1429 | ;; Check the cache. |
| 1428 | (try-completion string completions predicate))) | 1430 | (if (and (equal (nth 0 Info-complete-cache) Info-current-file) |
| 1429 | ((eq action t) | 1431 | (equal (nth 1 Info-complete-cache) Info-current-node) |
| 1430 | (let (completions | 1432 | (equal (nth 2 Info-complete-cache) Info-complete-next-re) |
| 1431 | (pattern (concat "\n\\* +\\(" | 1433 | (let ((prev (nth 3 Info-complete-cache))) |
| 1432 | (regexp-quote string) | 1434 | (eq t (compare-strings string 0 (length prev) |
| 1433 | "[^:\t\n]*\\):"))) | 1435 | prev 0 nil t)))) |
| 1434 | (save-excursion | 1436 | ;; We can reuse the previous list. |
| 1435 | (set-buffer Info-complete-menu-buffer) | 1437 | (setq completions (nth 4 Info-complete-cache)) |
| 1436 | (goto-char (point-min)) | 1438 | ;; The cache can't be used. |
| 1437 | (search-forward "\n* Menu:") | 1439 | (while |
| 1438 | (while (re-search-forward pattern nil t) | 1440 | (progn |
| 1439 | (setq completions (cons (cons | 1441 | (while (re-search-forward pattern nil t) |
| 1440 | (match-string-no-properties 1) | 1442 | (push (cons (match-string-no-properties 1) |
| 1441 | (match-beginning 1)) | 1443 | (match-beginning 1)) |
| 1442 | completions)))) | 1444 | completions)) |
| 1443 | (all-completions string completions predicate))) | 1445 | ;; Check subsequent nodes if applicable. |
| 1444 | (t | 1446 | (and Info-complete-next-re |
| 1445 | (save-excursion | 1447 | (setq nextnode (Info-extract-pointer "next" t)) |
| 1446 | (set-buffer Info-complete-menu-buffer) | 1448 | (string-match Info-complete-next-re nextnode))) |
| 1447 | (goto-char (point-min)) | 1449 | (Info-goto-node nextnode)) |
| 1448 | (search-forward "\n* Menu:") | 1450 | ;; Go back to the start node (for the next completion). |
| 1449 | (re-search-forward (concat "\n\\* +" | 1451 | (unless (equal Info-current-node orignode) |
| 1450 | (regexp-quote string) | 1452 | (Info-goto-node orignode)) |
| 1451 | ":") | 1453 | ;; Update the cache. |
| 1452 | nil t)))))) | 1454 | (setq Info-complete-cache |
| 1455 | (list Info-current-file Info-current-node | ||
| 1456 | Info-complete-next-re string completions))) | ||
| 1457 | (if action | ||
| 1458 | (all-completions string completions predicate) | ||
| 1459 | (try-completion string completions predicate))))))) | ||
| 1453 | 1460 | ||
| 1454 | 1461 | ||
| 1455 | (defun Info-menu (menu-item &optional fork) | 1462 | (defun Info-menu (menu-item &optional fork) |
| @@ -1817,35 +1824,46 @@ parent node." | |||
| 1817 | (error "No cross references in this node") | 1824 | (error "No cross references in this node") |
| 1818 | (Info-prev-reference t))))) | 1825 | (Info-prev-reference t))))) |
| 1819 | 1826 | ||
| 1827 | (defun Info-goto-index () | ||
| 1828 | (Info-goto-node "Top") | ||
| 1829 | (or (search-forward "\n* menu:" nil t) | ||
| 1830 | (error "No index")) | ||
| 1831 | (or (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t) | ||
| 1832 | (error "No index")) | ||
| 1833 | (goto-char (match-beginning 1)) | ||
| 1834 | (Info-goto-node (Info-extract-menu-node-name))) | ||
| 1835 | |||
| 1820 | (defun Info-index (topic) | 1836 | (defun Info-index (topic) |
| 1821 | "Look up a string TOPIC in the index for this file. | 1837 | "Look up a string TOPIC in the index for this file. |
| 1822 | The index is defined as the first node in the top-level menu whose | 1838 | The index is defined as the first node in the top level menu whose |
| 1823 | name contains the word \"Index\", plus any immediately following | 1839 | name contains the word \"Index\", plus any immediately following |
| 1824 | nodes whose names also contain the word \"Index\". | 1840 | nodes whose names also contain the word \"Index\". |
| 1825 | If there are no exact matches to the specified topic, this chooses | 1841 | If there are no exact matches to the specified topic, this chooses |
| 1826 | the first match which is a case-insensitive substring of a topic. | 1842 | the first match which is a case-insensitive substring of a topic. |
| 1827 | Use the `,' command to see the other matches. | 1843 | Use the `,' command to see the other matches. |
| 1828 | Give a blank topic name to go to the Index node itself." | 1844 | Give a blank topic name to go to the Index node itself." |
| 1829 | (interactive "sIndex topic: ") | 1845 | (interactive |
| 1846 | (list | ||
| 1847 | (let ((Info-complete-menu-buffer (clone-buffer)) | ||
| 1848 | (Info-complete-next-re "\\<Index\\>")) | ||
| 1849 | (unwind-protect | ||
| 1850 | (with-current-buffer Info-complete-menu-buffer | ||
| 1851 | (Info-goto-index) | ||
| 1852 | (completing-read "Index topic: " 'Info-complete-menu-item)) | ||
| 1853 | (kill-buffer Info-complete-menu-buffer))))) | ||
| 1830 | (let ((orignode Info-current-node) | 1854 | (let ((orignode Info-current-node) |
| 1831 | (rnode nil) | 1855 | (rnode nil) |
| 1832 | (pattern (format "\n\\* +\\([^\n:]*%s[^\n:]*\\):[ \t]*\\([^.\n]*\\)\\.[ \t]*\\([0-9]*\\)" | 1856 | (pattern (format "\n\\* +\\([^\n:]*%s[^\n:]*\\):[ \t]*\\([^.\n]*\\)\\.[ \t]*\\([0-9]*\\)" |
| 1833 | (regexp-quote topic))) | 1857 | (regexp-quote topic))) |
| 1834 | node | 1858 | node |
| 1835 | (case-fold-search t)) | 1859 | (case-fold-search t)) |
| 1836 | (Info-goto-node "Top") | ||
| 1837 | (or (search-forward "\n* menu:" nil t) | ||
| 1838 | (error "No index")) | ||
| 1839 | (or (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t) | ||
| 1840 | (error "No index")) | ||
| 1841 | (goto-char (match-beginning 1)) | ||
| 1842 | ;; Here, and subsequently in this function, | 1860 | ;; Here, and subsequently in this function, |
| 1843 | ;; we bind Info-history to nil for internal node-switches | 1861 | ;; we bind Info-history to nil for internal node-switches |
| 1844 | ;; so that we don't put junk in the history. | 1862 | ;; so that we don't put junk in the history. |
| 1845 | ;; In the first Info-goto-node call, above, we do update the history | 1863 | ;; In the first Info-goto-node call, above, we do update the history |
| 1846 | ;; because that is what the user's previous node choice into it. | 1864 | ;; because that is what the user's previous node choice into it. |
| 1847 | (let ((Info-history nil)) | 1865 | (let ((Info-history nil)) |
| 1848 | (Info-goto-node (Info-extract-menu-node-name))) | 1866 | (Info-goto-index)) |
| 1849 | (or (equal topic "") | 1867 | (or (equal topic "") |
| 1850 | (let ((matches nil) | 1868 | (let ((matches nil) |
| 1851 | (exact nil) | 1869 | (exact nil) |
| @@ -2156,8 +2174,7 @@ If no reference to follow, moves to the next node, or up if none." | |||
| 2156 | ;; Update menu menu. | 2174 | ;; Update menu menu. |
| 2157 | (let* ((Info-complete-menu-buffer (current-buffer)) | 2175 | (let* ((Info-complete-menu-buffer (current-buffer)) |
| 2158 | (items (nreverse (condition-case nil | 2176 | (items (nreverse (condition-case nil |
| 2159 | (Info-complete-menu-item | 2177 | (Info-complete-menu-item "" nil t) |
| 2160 | "" (lambda (e) t) t) | ||
| 2161 | (error nil)))) | 2178 | (error nil)))) |
| 2162 | entries current | 2179 | entries current |
| 2163 | (number 0)) | 2180 | (number 0)) |