Mercurial > emacs
changeset 10661:32beb7b6dbf7
Changes to support filenames as tags too and provided
a drop-in replacement for list-tags.
(find-tag-noselect): Recognize filenames as valid tags too.
(find-tag-file-order): New variable holds function to check for match
for a file name used as a tag.
(last-tag-file): New variable; stores the filename looked for via
find-tag family of functions.
(find-tag-in-order): If the tag is a file name, position at file beg.
(etags-recognize-tags-table): Added new var find-tag-file-order to
tags-table-format variables. Added tag-filename-match-p to the
list for find-tag-tag-order.
(tag-filename-match-p): New function.
(list-tags): Rewritten for speed.
(tags-list-functions-in-file): New subroutine for list-tags.
(tags-locate-file-in-tags-table): New function locates a
file in `tags-table-list'.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 05 Feb 1995 00:25:16 +0000 |
parents | 0501556eef3a |
children | cd968ab6a0eb |
files | lisp/progmodes/etags.el |
diffstat | 1 files changed, 112 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/progmodes/etags.el Sat Feb 04 17:59:47 1995 +0000 +++ b/lisp/progmodes/etags.el Sun Feb 05 00:25:16 1995 +0000 @@ -136,6 +136,8 @@ (defvar goto-tag-location-function nil "Function of to go to the location in the buffer specified by a tag. One argument, the tag info returned by `snarf-tag-function'.") +(defvar find-tag-file-order nil + "Function which checks for complete and correct match, for file name as tag.") (defvar find-tag-regexp-search-function nil "Search function passed to `find-tag-in-order' for finding a regexp tag.") (defvar find-tag-regexp-tag-order nil @@ -195,6 +197,8 @@ ;; Bind tags-file-name so we can control below whether the local or ;; global value gets set. Calling visit-tags-table-buffer will ;; initialize a buffer for the file and set tags-file-name to the + ;; Calling visit-tags-table-buffer with tags-file-name set to FILE will + ;; initialize a buffer for FILE and set tags-file-name to the ;; fully-expanded name. (let ((tags-file-name file)) (save-excursion @@ -712,7 +716,8 @@ (setq find-tag-history (cons tagname find-tag-history)) ;; Save the current buffer's value of `find-tag-hook' before selecting the ;; tags table buffer. - (let ((local-find-tag-hook find-tag-hook)) + (let ((local-find-tag-hook find-tag-hook) + (search-tag)) (if (eq '- next-p) ;; Pop back to a previous location. (if (null tags-location-stack) @@ -738,6 +743,7 @@ ;; Record the location so we can pop back to it later. (let ((marker (make-marker))) (save-excursion + (setq search-tag (if next-p last-tag tagname)) (set-buffer ;; find-tag-in-order does the real work. (find-tag-in-order @@ -747,7 +753,9 @@ find-tag-search-function) (if regexp-p find-tag-regexp-tag-order - find-tag-tag-order) + (if (string-match "\\b.*\\.\\w*" search-tag) + find-tag-file-order + find-tag-tag-order)) (if regexp-p find-tag-regexp-next-line-after-failure-p find-tag-next-line-after-failure-p) @@ -881,13 +889,15 @@ (first-table t) (tag-order order) goto-func + match-type ) (save-excursion (or first-search ;find-tag-noselect has already done it. (visit-tags-table-buffer 'same)) ;; Get a qualified match. - (catch 'qualified-match-found + (setq match-type + (catch 'qualified-match-found ;; Iterate over the list of tags tables. (while (or first-table @@ -899,6 +909,9 @@ (and first-search first-table ;; Start at beginning of tags file. (goto-char (point-min))) + (or first-table + (goto-char (point-min))) + (setq first-table nil) (setq tags-table-file buffer-file-name) @@ -920,7 +933,7 @@ (setq order tag-order)) ;; We throw out on match, so only get here if there were no matches. (error "No %stags %s %s" (if first-search "" "more ") - matching pattern)) + matching pattern))) ;; Found a tag; extract location info. (beginning-of-line) @@ -937,7 +950,9 @@ (set-buffer (find-file-noselect file)) (widen) (push-mark) - (funcall goto-func tag-info) + (if (eq match-type 'tag-filename-match-p) + (goto-char (point-min)) + (funcall goto-func tag-info)) ;; Return the buffer where the tag was found. (current-buffer)))) @@ -962,10 +977,12 @@ (find-tag-regexp-tag-order . (tag-re-match-p)) (find-tag-regexp-next-line-after-failure-p . t) (find-tag-search-function . search-forward) - (find-tag-tag-order . (tag-exact-match-p + (find-tag-tag-order . (tag-filename-match-p + tag-exact-match-p tag-symbol-match-p tag-word-match-p tag-any-match-p)) + (find-tag-file-order . (tag-filename-match-p)) (find-tag-next-line-after-failure-p . nil) (list-tags-function . etags-list-tags) (tags-apropos-function . etags-tags-apropos) @@ -1197,6 +1214,11 @@ (save-excursion (backward-char (1+ (length tag))) (looking-at "\\b")))) +(defun tag-filename-match-p (tag) + (and (looking-at ",") + (save-excursion (backward-char (1+ (length tag))) + (looking-at "\\b")))) + ;; t if point is in a tag line with a tag containing TAG as a substring. (defun tag-any-match-p (tag) (looking-at ".*\177")) @@ -1361,29 +1383,20 @@ (tags-loop-continue (or file-list-form t))) ;;;###autoload -(defun list-tags (file) - "Display list of tags in file FILE. -FILE should not contain a directory specification." - (interactive (list (completing-read "List tags in file: " - (save-excursion - (visit-tags-table-buffer) - (mapcar 'list - (mapcar 'file-name-nondirectory - (tags-table-files)))) - nil t nil))) - (with-output-to-temp-buffer "*Tags List*" - (princ "Tags in file ") - (princ file) - (terpri) - (save-excursion - (let ((first-time t) - (gotany nil)) - (while (visit-tags-table-buffer (not first-time)) - (setq first-time nil) - (if (funcall list-tags-function file) - (setq gotany t))) - (or gotany - (error "File %s not in current tags tables" file)))))) +(defun list-tags (filename &optional next-match) + "Gives the list of functions available in file \"filename\" +Searches only in \"tags-file-name\"." + (interactive "sFunctions in File: ") + (let (file-list) + (setq file-list (tags-locate-file-in-tags-table filename + (if next-match next-match nil))) + (if file-list + (if (cdr file-list) + (select-tags-matched-file file-list 'extract-pos-and-tag-from-sel + 'select-file-quit) + (tags-list-functions-in-file (nth 1 (car file-list)) + (nth 2 (car file-list)))) + (message (format "%s not found in tags table" filename))))) ;;;###autoload (defun tags-apropos (regexp) @@ -1531,6 +1544,76 @@ ;;;###autoload (define-key esc-map "\t" 'complete-tag) +(defun tags-list-functions-in-file (pos tag-file) + "Lists the functions for the given file. Backend for `list-tags'." + (let ((tag-buf (find-file-noselect tag-file)) + (result-buf (get-buffer-create "*Tags Function List*")) + function + beg + map) + (save-excursion + (set-buffer result-buf) + (erase-buffer) + (set-buffer tag-buf) + (goto-char pos) + (forward-line 1) + (beginning-of-line) + ; C-l marks end of information of a file in TAGS. + (while (and (not (looking-at "^\C-l")) (not (eobp))) + ; skip mere #defines, typedefs and struct definitions + (if (not (or (looking-at "^#define\\s-+[a-zA-Z0-9_]+\\s-+") + (looking-at "^typedef\\s-+") + (looking-at "^\\s-*}"))) + (progn + (setq beg (point)) + (skip-chars-forward "^\C-?(") + (setq function (buffer-substring beg (point))) + (save-excursion + (set-buffer result-buf) + (insert (concat function "\n"))))) + (forward-line 1) + (beginning-of-line))) + (switch-to-buffer "*Tags Function List*") + (goto-char 1) + (set-buffer-modified-p nil) + (setq buffer-read-only t))) + +(defun tags-locate-file-in-tags-table (filename first-search) + "This function is used to locate `filename' in `tags-table-list'. + Its internally used by the functions `find-file-from-tags' and + `tags-list-tags-in-file'. If `first-search' is t, search continues from where + it left off last time. Else, its a fresh search." + (let (tag-list current-tags-buffer beg file found-file-list next-tag-file) + (setq tag-list tags-table-list) + (catch 'found-file + (setq found-file-list nil + next-tag-file nil) + (while tag-list + (setq current-tags-buffer (find-file-noselect (car tag-list))) + (save-excursion + (set-buffer current-tags-buffer) + (if (or next-tag-file + (not first-search)) + (goto-char (point-min))) + (if (search-forward filename nil t) + (if (tag-filename-match-p filename) + (progn + (beginning-of-line) + (setq beg (point)) + (skip-chars-forward "^,") + (or (looking-at ",include$") + (setq file (expand-file-name (buffer-substring beg + (point))))) + (if (string-match filename (file-name-nondirectory file)) + (progn + (setq found-file-list (cons (list file (point) + (buffer-file-name)) + found-file-list)) + (throw 'found-file found-file-list)))))) + (setq tag-list (cdr tag-list)) + (setq next-tag-file 't))) + (throw 'found-file found-file-list)))) + (provide 'etags) ;;; etags.el ends here