Function: visit-tags-table-buffer

visit-tags-table-buffer is an autoloaded and byte-compiled function defined in etags.el.gz.

Signature

(visit-tags-table-buffer &optional CONT CBUF)

Documentation

Select the buffer containing the current tags table.

Optional arg CONT specifies which tags table to visit. If CONT is a string, visit that file as a tags table. If CONT is t, visit the next table in tags-table-list. If CONT is the atom same, don't look for a new table;
 just select the buffer visiting tags-file-name.
If CONT is nil or absent, choose a first buffer from information in
 tags-file-name, tags-table-list, tags-table-list-pointer.
Optional second arg CBUF, if non-nil, specifies the initial buffer, which is important if that buffer has a local value of tags-file-name. Returns t if it visits a tags table, or nil if there are no more in the list.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/etags.el.gz
;;;###autoload
(defun visit-tags-table-buffer (&optional cont cbuf)
  "Select the buffer containing the current tags table.
Optional arg CONT specifies which tags table to visit.
If CONT is a string, visit that file as a tags table.
If CONT is t, visit the next table in `tags-table-list'.
If CONT is the atom `same', don't look for a new table;
 just select the buffer visiting `tags-file-name'.
If CONT is nil or absent, choose a first buffer from information in
 `tags-file-name', `tags-table-list', `tags-table-list-pointer'.
Optional second arg CBUF, if non-nil, specifies the initial buffer,
which is important if that buffer has a local value of `tags-file-name'.
Returns t if it visits a tags table, or nil if there are no more in the list."

  ;; Set tags-file-name to the tags table file we want to visit.
  (if cbuf (set-buffer cbuf))
  (cond ((eq cont 'same)
	 ;; Use the ambient value of tags-file-name.
	 (or tags-file-name
	     (user-error "%s"
                         (substitute-command-keys
                          (concat "No tags table in use; "
                                  "use \\[visit-tags-table] to select one")))))
	((eq t cont)
	 ;; Find the next table.
	 (if (tags-next-table)
	     ;; Skip over nonexistent files.
	     (while (and (not (or (get-file-buffer tags-file-name)
				  (file-exists-p tags-file-name)))
			 (tags-next-table)))))
	(t
	 ;; Pick a table out of our hat.
	 (tags-table-check-computed-list) ;Get it up to date, we might use it.
	 (setq tags-file-name
	       (or
		;; If passed a string, use that.
		(if (stringp cont)
		    (prog1 cont
		      (setq cont nil)))
		;; First, try a local variable.
		(cdr (assq 'tags-file-name (buffer-local-variables)))
		;; Second, try a user-specified function to guess.
		(and default-tags-table-function
		     (funcall default-tags-table-function))
		;; Third, look for a tags table that contains tags for the
		;; current buffer's file.  If one is found, the lists will
		;; be frobnicated, and CONT will be set non-nil so we don't
		;; do it below.
		(and buffer-file-name
                     (save-current-buffer
                       (or
                        ;; First check only tables already in buffers.
                        (tags-table-including buffer-file-name t)
                        ;; Since that didn't find any, now do the
                        ;; expensive version: reading new files.
                        (tags-table-including buffer-file-name nil))))
		;; Fourth, use the user variable tags-file-name, if it is
		;; not already in the current list.
		(and tags-file-name
		     (not (tags-table-list-member tags-file-name
						  tags-table-computed-list))
		     tags-file-name)
		;; Fifth, use the user variable giving the table list.
		;; Find the first element of the list that actually exists.
		(let ((list tags-table-list)
		      file)
		  (while (and list
			      (setq file (tags-expand-table-name (car list)))
			      (not (get-file-buffer file))
			      (not (file-exists-p file)))
		    (setq list (cdr list)))
		  (car list))
		;; Finally, prompt the user for a file name.
		(expand-file-name
		 (read-file-name "Visit tags table (default TAGS): "
				 default-directory
				 "TAGS"
				 t))))))

  ;; Expand the table name into a full file name.
  (setq tags-file-name (tags-expand-table-name tags-file-name))

  (unless (and (eq cont t) (null tags-table-list-pointer))
    ;; Verify that tags-file-name names a valid tags table.
    ;; Bind another variable with the value of tags-file-name
    ;; before we switch buffers, in case tags-file-name is buffer-local.
    (let ((curbuf (current-buffer))
	  (local-tags-file-name tags-file-name))
      (if (tags-verify-table local-tags-file-name)

	  ;; We have a valid tags table.
	  (progn
	    ;; Bury the tags table buffer so it
	    ;; doesn't get in the user's way.
	    (bury-buffer (current-buffer))

	    ;; If this was a new table selection (CONT is nil), make
	    ;; sure tags-table-list includes the chosen table, and
	    ;; update the list pointer variables.
	    (or cont
		;; Look in the list for the table we chose.
		(let ((found (tags-table-list-member
			      local-tags-file-name
			      tags-table-computed-list)))
		  (if found
		      ;; There it is.  Just switch to it.
		      (setq tags-table-list-pointer found
			    tags-table-list-started-at found)

		    ;; The table is not in the current set.
		    ;; Try to find it in another previously used set.
		    (let ((sets tags-table-set-list))
		      (while (and sets
				  (not (tags-table-list-member
					local-tags-file-name
					(car sets))))
			(setq sets (cdr sets)))
		      (if sets
			  ;; Found in some other set.  Switch to that set.
			  (progn
			    (or (memq tags-table-list tags-table-set-list)
				;; Save the current list.
				(setq tags-table-set-list
				      (cons tags-table-list
					    tags-table-set-list)))
			    (setq tags-table-list (car sets)))

			;; Not found in any existing set.
			(if (and tags-table-list
				 (or (eq t tags-add-tables)
				     (and tags-add-tables
					  (y-or-n-p
					   (concat "Keep current list of "
						   "tags tables also? ")))))
			    ;; Add it to the current list.
			    (setq tags-table-list (cons local-tags-file-name
							tags-table-list))

			  ;; Make a fresh list, and store the old one.
			  (message "Starting a new list of tags tables")
			  (or (null tags-table-list)
			      (memq tags-table-list tags-table-set-list)
			      (setq tags-table-set-list
				    (cons tags-table-list
					  tags-table-set-list)))
			  ;; Clear out buffers holding old tables.
			  (dolist (table tags-table-list)
			    ;; The list can contain items t.
			    (if (stringp table)
				(let ((buffer (find-buffer-visiting table)))
			      (if buffer
				  (kill-buffer buffer)))))
			  (setq tags-table-list (list local-tags-file-name))))

		      ;; Recompute tags-table-computed-list.
		      (tags-table-check-computed-list)
		      ;; Set the tags table list state variables to start
		      ;; over from tags-table-computed-list.
		      (setq tags-table-list-started-at tags-table-computed-list
			    tags-table-list-pointer
			    tags-table-computed-list)))))

	    ;; Return of t says the tags table is valid.
	    t)

	;; The buffer was not valid.  Don't use it again.
	(set-buffer curbuf)
	(kill-local-variable 'tags-file-name)
	(if (eq local-tags-file-name tags-file-name)
	    (setq tags-file-name nil))
	(user-error (if (file-exists-p local-tags-file-name)
                        "File %s is not a valid tags table"
                      "File %s does not exist")
                    local-tags-file-name)))))