* lisp/info.el (Info-file-completions): New variable.

(Info-read-node-name-1): Complete node names in the Info file
when a file name is given.  Call `Info-build-node-completions'
with a file name.
(Info-build-node-completions): Add new arg `file'.  When it is
non-nil, visit it in a temporary buffer and cache its completions in
`Info-current-file-completions'.  Move most of the function body to
`Info-build-node-completions-1'.
(Info-build-node-completions-1): New function with the body from
`Info-build-node-completions'.

Fixes: debbugs:12456
This commit is contained in:
Juri Linkov 2012-12-27 22:42:02 +02:00
parent a45b76475e
commit 313f39aa03
2 changed files with 78 additions and 40 deletions

View file

@ -1,3 +1,16 @@
2012-12-27 Juri Linkov <juri@jurta.org>
* info.el (Info-file-completions): New variable.
(Info-read-node-name-1): Complete node names in the Info file
when a file name is given. Call `Info-build-node-completions'
with a file name.
(Info-build-node-completions): Add new arg `file'. When it is
non-nil, visit it in a temporary buffer and cache its completions in
`Info-current-file-completions'. Move most of the function body to
`Info-build-node-completions-1'.
(Info-build-node-completions-1): New function with the body from
`Info-build-node-completions'. (Bug#12456)
2012-12-27 Juri Linkov <juri@jurta.org>
* frame.el (frame-maximization-style): Remove user option.

View file

@ -397,6 +397,10 @@ Marker points nowhere if file has no tag table.")
(defvar Info-current-file-completions nil
"Cached completion list for current Info file.")
(defvar Info-file-completions nil
"Cached completion alist of visited Info files.
Each element of the alist is (FILE . COMPLETIONS)")
(defvar Info-file-supports-index-cookies nil
"Non-nil if current Info file supports index cookies.")
@ -1771,12 +1775,20 @@ See `completing-read' for a description of arguments and usage."
(substring string 1)
predicate
code))
;; If a file name was given, then any node is fair game.
((string-match "\\`(" string)
(cond
((eq code nil) string)
((eq code t) nil)
(t t)))
;; If a file name was given, complete nodes in the file.
((string-match "\\`(\\([^)]+\\))" string)
(let ((file0 (match-string 0 string))
(file1 (match-string 1 string))
(node (substring string (match-end 0))))
(completion-table-with-context
file0
(apply-partially
(lambda (string pred action)
(complete-with-action
action
(Info-build-node-completions (Info-find-file file1))
string pred)))
node predicate code)))
;; Otherwise use Info-read-node-completion-table.
(t (complete-with-action
code Info-read-node-completion-table string predicate))))
@ -1793,41 +1805,54 @@ in the current Info file, or \"(FILENAME)NODENAME\"."
(Info-read-node-name prompt)
nodename)))
(defun Info-build-node-completions ()
(or Info-current-file-completions
(let ((compl nil)
;; Bind this in case the user sets it to nil.
(case-fold-search t)
(node-regexp "Node: *\\([^,\n]*\\) *[,\n\t]"))
(save-excursion
(save-restriction
(or Info-tag-table-marker
(error "No Info tags found"))
(if (marker-buffer Info-tag-table-marker)
(let ((marker Info-tag-table-marker))
(set-buffer (marker-buffer marker))
(widen)
(goto-char marker)
(while (re-search-forward "\n\\(Node\\|Ref\\): \\(.*\\)\177" nil t)
(setq compl
(cons (list (match-string-no-properties 2))
compl))))
(defun Info-build-node-completions (&optional file)
(if file
(or (cdr (assoc file Info-file-completions))
(with-temp-buffer
(Info-mode)
(Info-goto-node (format "(%s)Top" file))
(Info-build-node-completions-1)
(push (cons file Info-current-file-completions) Info-file-completions)
Info-current-file-completions))
(or Info-current-file-completions
(Info-build-node-completions-1))))
(defun Info-build-node-completions-1 ()
(let ((compl nil)
;; Bind this in case the user sets it to nil.
(case-fold-search t)
(node-regexp "Node: *\\([^,\n]*\\) *[,\n\t]"))
(save-excursion
(save-restriction
(or Info-tag-table-marker
(error "No Info tags found"))
(if (marker-buffer Info-tag-table-marker)
(let ((marker Info-tag-table-marker))
(set-buffer (marker-buffer marker))
(widen)
(goto-char (point-min))
;; If the buffer begins with a node header, process that first.
(if (Info-node-at-bob-matching node-regexp)
(setq compl (list (match-string-no-properties 1))))
;; Now for the rest of the nodes.
(while (search-forward "\n\^_" nil t)
(forward-line 1)
(let ((beg (point)))
(forward-line 1)
(if (re-search-backward node-regexp beg t)
(setq compl
(cons (list (match-string-no-properties 1))
compl))))))))
(setq compl (cons '("*") compl))
(set (make-local-variable 'Info-current-file-completions) compl))))
(goto-char marker)
(while (re-search-forward "\n\\(Node\\|Ref\\): \\(.*\\)\177" nil t)
(setq compl
(cons (list (match-string-no-properties 2))
compl))))
(widen)
(goto-char (point-min))
;; If the buffer begins with a node header, process that first.
(if (Info-node-at-bob-matching node-regexp)
(setq compl (list (match-string-no-properties 1))))
;; Now for the rest of the nodes.
(while (search-forward "\n\^_" nil t)
(forward-line 1)
(let ((beg (point)))
(forward-line 1)
(if (re-search-backward node-regexp beg t)
(setq compl
(cons (list (match-string-no-properties 1))
compl))))))))
(setq compl (cons '("*") (nreverse compl)))
(set (make-local-variable 'Info-current-file-completions) compl)
compl))
(defun Info-restore-point (hl)
"If this node has been visited, restore the point value when we left."