Function: find-tag-in-order
find-tag-in-order is a byte-compiled function defined in etags.el.gz.
Signature
(find-tag-in-order PATTERN SEARCH-FORWARD-FUNC ORDER NEXT-LINE-AFTER-FAILURE-P MATCHING FIRST-SEARCH)
Documentation
Internal tag-finding function.
PATTERN is a string to pass to arg SEARCH-FORWARD-FUNC, and to any member of the function list ORDER. If ORDER is nil, use saved state to continue a previous search.
Arg NEXT-LINE-AFTER-FAILURE-P is non-nil if after a failed match, point should be moved to the next line.
Arg MATCHING is a string, an English -ing word, to be used in an
error message.
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/etags.el.gz
"Matches remembered between calls.") ; Doc string: calls to what?
(defun find-tag-in-order (pattern
search-forward-func
order
next-line-after-failure-p
matching
first-search)
"Internal tag-finding function.
PATTERN is a string to pass to arg SEARCH-FORWARD-FUNC, and to any
member of the function list ORDER. If ORDER is nil, use saved state
to continue a previous search.
Arg NEXT-LINE-AFTER-FAILURE-P is non-nil if after a failed match,
point should be moved to the next line.
Arg MATCHING is a string, an English `-ing' word, to be used in an
error message."
;; Algorithm is as follows:
;; For each qualifier-func in ORDER, go to beginning of tags file, and
;; perform inner loop: for each naive match for PATTERN found using
;; SEARCH-FORWARD-FUNC, qualify the naive match using qualifier-func. If
;; it qualifies, go to the specified line in the specified source file
;; and return. Qualified matches are remembered to avoid repetition.
;; State is saved so that the loop can be continued.
(let (file ;name of file containing tag
tag-info ;where to find the tag in FILE
(first-table t)
(tag-order order)
(match-marker (make-marker))
goto-func
(case-fold-search (if (memq tags-case-fold-search '(nil t))
tags-case-fold-search
case-fold-search))
(cbuf (current-buffer))
)
(save-excursion
(if first-search
;; This is the start of a search for a fresh tag.
;; Clear the list of tags matched by the previous search.
;; find-tag-noselect has already put us in the first tags table
;; buffer before we got called.
(setq tag-lines-already-matched nil)
;; Continuing to search for the tag specified last time.
;; tag-lines-already-matched lists locations matched in previous
;; calls so we don't visit the same tag twice if it matches twice
;; during two passes with different qualification predicates.
;; Switch to the current tags table buffer.
(visit-tags-table-buffer 'same))
;; Get a qualified match.
(catch 'qualified-match-found
;; Iterate over the list of tags tables.
(while (or first-table (visit-tags-table-buffer t cbuf))
(and first-search first-table
;; Start at beginning of tags file.
(goto-char (point-min)))
(setq first-table nil)
;; Iterate over the list of ordering predicates.
(while order
(while (funcall search-forward-func pattern nil t)
;; Naive match found. Qualify the match.
(and (funcall (car order) pattern)
;; Make sure it is not a previous qualified match.
(not (member (set-marker match-marker (point-at-bol))
tag-lines-already-matched))
(throw 'qualified-match-found nil))
(if next-line-after-failure-p
(forward-line 1)))
;; Try the next flavor of match.
(setq order (cdr order))
(goto-char (point-min)))
(setq order tag-order))
;; We throw out on match, so only get here if there were no matches.
;; Clear out the markers we use to avoid duplicate matches so they
;; don't slow down editing and are immediately available for GC.
(while tag-lines-already-matched
(set-marker (car tag-lines-already-matched) nil nil)
(setq tag-lines-already-matched (cdr tag-lines-already-matched)))
(set-marker match-marker nil nil)
(user-error "No %stags %s %s" (if first-search "" "more ")
matching pattern))
;; Found a tag; extract location info.
(beginning-of-line)
(setq tag-lines-already-matched (cons match-marker
tag-lines-already-matched))
;; Expand the filename, using the tags table buffer's default-directory.
;; We should be able to search for file-name backwards in file-of-tag:
;; the beginning-of-line is ok except when positioned on a "file-name" tag.
(setq file (expand-file-name
(if (memq (car order) '(tag-exact-file-name-match-p
tag-file-name-match-p
tag-partial-file-name-match-p))
(save-excursion (forward-line 1)
(file-of-tag))
(file-of-tag)))
tag-info (funcall snarf-tag-function))
;; Get the local value in the tags table buffer before switching buffers.
(setq goto-func goto-tag-location-function)
(tag-find-file-of-tag-noselect file)
(widen)
(push-mark)
(funcall goto-func tag-info)
;; Return the buffer where the tag was found.
(current-buffer))))