Mercurial > emacs
changeset 16981:643e0f90e153
Handle multiple Info buffers.
(Info-tag-table-marker): Initialize to nil.
(Info-tag-table-buffer): New variable.
(Info-find-node): Don't switch buffers if already in Info mode.
Use Info-tag-table-buffer to support multiple Info buffers.
(Info-read-subfile): Don't switch to *info* buffer.
(Info-build-node-completions): Handle buffer local bindings for
Info-tag-table-marker.
(Info-search): Add a save-excursion.
(Info-mode): Make Info-tag-table-buffer buffer-local.
Make a different marker in Info-tag-table-marker for each buffer.
(Info-kill-buffer): New function, on kill-buffer-hook.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 08 Feb 1997 18:34:21 +0000 |
parents | 3da3a2934be5 |
children | 8516fb50f3e5 |
files | lisp/info.el |
diffstat | 1 files changed, 87 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/info.el Sat Feb 08 15:50:17 1997 +0000 +++ b/lisp/info.el Sat Feb 08 18:34:21 1997 +0000 @@ -114,10 +114,13 @@ (defvar Info-current-node nil "Name of node that Info is now looking at, or nil.") -(defvar Info-tag-table-marker (make-marker) +(defvar Info-tag-table-marker nil "Marker pointing at beginning of current Info file's tag table. Marker points nowhere if file has no tag table.") +(defvar Info-tag-table-buffer nil + "Buffer used for indirect tag tables.") + (defvar Info-current-file-completions nil "Cached completion list for current Info file.") @@ -301,7 +304,7 @@ (cons (list Info-current-file Info-current-node (point)) Info-history))) ;; Go into info buffer. - (pop-to-buffer "*info*") + (or (eq major-mode 'Info-mode) (pop-to-buffer "*info*")) (buffer-disable-undo (current-buffer)) (or (eq major-mode 'Info-mode) (Info-mode)) @@ -324,12 +327,12 @@ (setq default-directory (file-name-directory filename))) (set-buffer-modified-p nil) ;; See whether file has a tag table. Record the location if yes. - (set-marker Info-tag-table-marker nil) (goto-char (point-max)) (forward-line -8) ;; Use string-equal, not equal, to ignore text props. - (or (string-equal nodename "*") - (not (search-forward "\^_\nEnd tag table\n" nil t)) + (if (not (or (string-equal nodename "*") + (not + (search-forward "\^_\nEnd tag table\n" nil t)))) (let (pos) ;; We have a tag table. Find its beginning. ;; Is this an indirect file? @@ -340,16 +343,21 @@ (looking-at "(Indirect)\n")) ;; It is indirect. Copy it to another buffer ;; and record that the tag table is in that buffer. - (save-excursion - (let ((buf (current-buffer))) - (set-buffer (get-buffer-create " *info tag table*")) + (let ((buf (current-buffer)) + (tagbuf + (or Info-tag-table-buffer + (generate-new-buffer " *info tag table*")))) + (setq Info-tag-table-buffer tagbuf) + (save-excursion + (set-buffer tagbuf) (buffer-disable-undo (current-buffer)) (setq case-fold-search t) (erase-buffer) - (insert-buffer-substring buf) - (set-marker Info-tag-table-marker - (match-end 0)))) - (set-marker Info-tag-table-marker pos)))) + (insert-buffer-substring buf)) + (set-marker Info-tag-table-marker + (match-end 0) tagbuf)) + (set-marker Info-tag-table-marker pos))) + (set-marker Info-tag-table-marker nil)) (setq Info-current-file (if (eq filename t) "dir" filename)))) ;; Use string-equal, not equal, to ignore text props. @@ -364,18 +372,28 @@ ;; read the proper subfile into this buffer. (if (marker-position Info-tag-table-marker) (save-excursion - (set-buffer (marker-buffer Info-tag-table-marker)) - (goto-char Info-tag-table-marker) - (if (re-search-forward regexp nil t) - (progn - (setq guesspos (read (current-buffer))) - ;; If this is an indirect file, - ;; determine which file really holds this node - ;; and read it in. - (if (not (eq (current-buffer) (get-buffer "*info*"))) - (setq guesspos - (Info-read-subfile guesspos)))) - (error "No such node: %s" nodename)))) + (let ((m Info-tag-table-marker) + found found-mode) + (save-excursion + (set-buffer (marker-buffer m)) + (goto-char m) + (beginning-of-line) ;so re-search will work. + (setq found (re-search-forward regexp nil t)) + (if found + (setq guesspos (read (current-buffer)))) + (setq found-mode major-mode)) + (if found + (progn + ;; If this is an indirect file, determine + ;; which file really holds this node and + ;; read it in. + (if (not (eq found-mode 'Info-mode)) + ;; Note that the current buffer must be + ;; the *info* buffer on entry to + ;; Info-read-subfile. Thus the hackery + ;; above. + (setq guesspos (Info-read-subfile guesspos)))) + (error "No such node: %s" nodename))))) (goto-char (max (point-min) (- guesspos 1000))) ;; Now search from our advised position (or from beg of buffer) ;; to find the actual node. @@ -548,6 +566,8 @@ (setq Info-dir-contents (buffer-string))) (setq default-directory Info-dir-contents-directory)) +;; Note that on entry to this function the current-buffer must be the +;; *info* buffer; not the info tags buffer. (defun Info-read-subfile (nodepos) ;; NODEPOS is either a position (in the Info file as a whole, ;; not relative to a subfile) or the name of a subfile. @@ -577,7 +597,8 @@ (forward-line 1))))) (setq lastfilename nodepos) (setq lastfilepos 0)) - (set-buffer (get-buffer "*info*")) + ;; Assume previous buffer is in Info-mode. + ;; (set-buffer (get-buffer "*info*")) (or (equal Info-current-subfile lastfilename) (let ((buffer-read-only nil)) (setq buffer-file-name nil) @@ -686,10 +707,10 @@ (save-excursion (save-restriction (if (marker-buffer Info-tag-table-marker) - (progn - (set-buffer (marker-buffer Info-tag-table-marker)) + (let ((marker Info-tag-table-marker)) + (set-buffer (marker-buffer marker)) (widen) - (goto-char Info-tag-table-marker) + (goto-char marker) (while (re-search-forward "\nNode: \\(.*\\)\177" nil t) (setq compl (cons (list (buffer-substring (match-beginning 1) @@ -747,27 +768,28 @@ (if (not found) ;can only happen in subfile case -- else would have erred (unwind-protect (let ((list ())) - (set-buffer (marker-buffer Info-tag-table-marker)) - (goto-char (point-min)) - (search-forward "\n\^_\nIndirect:") - (save-restriction - (narrow-to-region (point) - (progn (search-forward "\n\^_") - (1- (point)))) + (save-excursion + (set-buffer (marker-buffer Info-tag-table-marker)) (goto-char (point-min)) - (search-forward (concat "\n" osubfile ": ")) - (beginning-of-line) - (while (not (eobp)) - (re-search-forward "\\(^.*\\): [0-9]+$") - (goto-char (+ (match-end 1) 2)) - (setq list (cons (cons (read (current-buffer)) - (buffer-substring (match-beginning 1) - (match-end 1))) - list)) - (goto-char (1+ (match-end 0)))) - (setq list (nreverse list) - current (car (car list)) - list (cdr list))) + (search-forward "\n\^_\nIndirect:") + (save-restriction + (narrow-to-region (point) + (progn (search-forward "\n\^_") + (1- (point)))) + (goto-char (point-min)) + (search-forward (concat "\n" osubfile ": ")) + (beginning-of-line) + (while (not (eobp)) + (re-search-forward "\\(^.*\\): [0-9]+$") + (goto-char (+ (match-end 1) 2)) + (setq list (cons (cons (read (current-buffer)) + (buffer-substring + (match-beginning 1) (match-end 1))) + list)) + (goto-char (1+ (match-end 0)))) + (setq list (nreverse list) + current (car (car list)) + list (cdr list)))) (while list (message "Searching subfile %s..." (cdr (car list))) (Info-read-subfile (car (car list))) @@ -809,7 +831,7 @@ ;; Return the node name in the buffer following point. ;; ALLOWEDCHARS, if non-nil, goes within [...] to make a regexp -;; saying which chas may appear in the node name. +;; saying which chars may appear in the node name. (defun Info-following-node-name (&optional allowedchars) (skip-chars-forward " \t") (buffer-substring-no-properties @@ -1735,6 +1757,9 @@ (make-local-variable 'Info-current-subfile) (make-local-variable 'Info-current-node) (make-local-variable 'Info-tag-table-marker) + (setq Info-tag-table-marker (make-marker)) + (make-local-variable 'Info-tag-table-buffer) + (setq Info-tag-table-buffer nil) (make-local-variable 'Info-history) (make-local-variable 'Info-index-alternatives) (if (memq (framep (selected-frame)) '(x pc w32)) @@ -1874,6 +1899,8 @@ ;; Get Info running, and pop to it in another window. (save-window-excursion (info)) + ;; FIXME It would be cool if this could use a buffer other + ;; than *info*. (pop-to-buffer "*info*") (Info-find-node (car (car where)) (car (cdr (car where)))) @@ -1962,6 +1989,17 @@ (put-text-property (match-beginning 1) (match-end 1) 'mouse-face 'highlight)))) (set-buffer-modified-p nil)))) + + +;; 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) + Info-tag-table-buffer + (kill-buffer Info-tag-table-buffer))) + +(add-hook 'kill-buffer-hook 'Info-kill-buffer) + (provide 'info)