diff options
| author | Richard M. Stallman | 1995-02-05 00:25:16 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-02-05 00:25:16 +0000 |
| commit | 5e882a6a2274cbf0141bc460500f72e056148002 (patch) | |
| tree | dd54c2d50d0af0097bed16f896fa84f9983fab2b | |
| parent | d2956936d3f805740611123d97af64b9e8a01121 (diff) | |
| download | emacs-5e882a6a2274cbf0141bc460500f72e056148002.tar.gz emacs-5e882a6a2274cbf0141bc460500f72e056148002.zip | |
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'.
| -rw-r--r-- | lisp/progmodes/etags.el | 141 |
1 files changed, 112 insertions, 29 deletions
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index 5066514687d..c0b04613ef0 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el | |||
| @@ -136,6 +136,8 @@ of the format-parsing tags function variables if successful.") | |||
| 136 | (defvar goto-tag-location-function nil | 136 | (defvar goto-tag-location-function nil |
| 137 | "Function of to go to the location in the buffer specified by a tag. | 137 | "Function of to go to the location in the buffer specified by a tag. |
| 138 | One argument, the tag info returned by `snarf-tag-function'.") | 138 | One argument, the tag info returned by `snarf-tag-function'.") |
| 139 | (defvar find-tag-file-order nil | ||
| 140 | "Function which checks for complete and correct match, for file name as tag.") | ||
| 139 | (defvar find-tag-regexp-search-function nil | 141 | (defvar find-tag-regexp-search-function nil |
| 140 | "Search function passed to `find-tag-in-order' for finding a regexp tag.") | 142 | "Search function passed to `find-tag-in-order' for finding a regexp tag.") |
| 141 | (defvar find-tag-regexp-tag-order nil | 143 | (defvar find-tag-regexp-tag-order nil |
| @@ -195,6 +197,8 @@ file the tag was in." | |||
| 195 | ;; Bind tags-file-name so we can control below whether the local or | 197 | ;; Bind tags-file-name so we can control below whether the local or |
| 196 | ;; global value gets set. Calling visit-tags-table-buffer will | 198 | ;; global value gets set. Calling visit-tags-table-buffer will |
| 197 | ;; initialize a buffer for the file and set tags-file-name to the | 199 | ;; initialize a buffer for the file and set tags-file-name to the |
| 200 | ;; Calling visit-tags-table-buffer with tags-file-name set to FILE will | ||
| 201 | ;; initialize a buffer for FILE and set tags-file-name to the | ||
| 198 | ;; fully-expanded name. | 202 | ;; fully-expanded name. |
| 199 | (let ((tags-file-name file)) | 203 | (let ((tags-file-name file)) |
| 200 | (save-excursion | 204 | (save-excursion |
| @@ -712,7 +716,8 @@ See documentation of variable `tags-file-name'." | |||
| 712 | (setq find-tag-history (cons tagname find-tag-history)) | 716 | (setq find-tag-history (cons tagname find-tag-history)) |
| 713 | ;; Save the current buffer's value of `find-tag-hook' before selecting the | 717 | ;; Save the current buffer's value of `find-tag-hook' before selecting the |
| 714 | ;; tags table buffer. | 718 | ;; tags table buffer. |
| 715 | (let ((local-find-tag-hook find-tag-hook)) | 719 | (let ((local-find-tag-hook find-tag-hook) |
| 720 | (search-tag)) | ||
| 716 | (if (eq '- next-p) | 721 | (if (eq '- next-p) |
| 717 | ;; Pop back to a previous location. | 722 | ;; Pop back to a previous location. |
| 718 | (if (null tags-location-stack) | 723 | (if (null tags-location-stack) |
| @@ -738,6 +743,7 @@ See documentation of variable `tags-file-name'." | |||
| 738 | ;; Record the location so we can pop back to it later. | 743 | ;; Record the location so we can pop back to it later. |
| 739 | (let ((marker (make-marker))) | 744 | (let ((marker (make-marker))) |
| 740 | (save-excursion | 745 | (save-excursion |
| 746 | (setq search-tag (if next-p last-tag tagname)) | ||
| 741 | (set-buffer | 747 | (set-buffer |
| 742 | ;; find-tag-in-order does the real work. | 748 | ;; find-tag-in-order does the real work. |
| 743 | (find-tag-in-order | 749 | (find-tag-in-order |
| @@ -747,7 +753,9 @@ See documentation of variable `tags-file-name'." | |||
| 747 | find-tag-search-function) | 753 | find-tag-search-function) |
| 748 | (if regexp-p | 754 | (if regexp-p |
| 749 | find-tag-regexp-tag-order | 755 | find-tag-regexp-tag-order |
| 750 | find-tag-tag-order) | 756 | (if (string-match "\\b.*\\.\\w*" search-tag) |
| 757 | find-tag-file-order | ||
| 758 | find-tag-tag-order)) | ||
| 751 | (if regexp-p | 759 | (if regexp-p |
| 752 | find-tag-regexp-next-line-after-failure-p | 760 | find-tag-regexp-next-line-after-failure-p |
| 753 | find-tag-next-line-after-failure-p) | 761 | find-tag-next-line-after-failure-p) |
| @@ -881,13 +889,15 @@ See documentation of variable `tags-file-name'." | |||
| 881 | (first-table t) | 889 | (first-table t) |
| 882 | (tag-order order) | 890 | (tag-order order) |
| 883 | goto-func | 891 | goto-func |
| 892 | match-type | ||
| 884 | ) | 893 | ) |
| 885 | (save-excursion | 894 | (save-excursion |
| 886 | (or first-search ;find-tag-noselect has already done it. | 895 | (or first-search ;find-tag-noselect has already done it. |
| 887 | (visit-tags-table-buffer 'same)) | 896 | (visit-tags-table-buffer 'same)) |
| 888 | 897 | ||
| 889 | ;; Get a qualified match. | 898 | ;; Get a qualified match. |
| 890 | (catch 'qualified-match-found | 899 | (setq match-type |
| 900 | (catch 'qualified-match-found | ||
| 891 | 901 | ||
| 892 | ;; Iterate over the list of tags tables. | 902 | ;; Iterate over the list of tags tables. |
| 893 | (while (or first-table | 903 | (while (or first-table |
| @@ -899,6 +909,9 @@ See documentation of variable `tags-file-name'." | |||
| 899 | (and first-search first-table | 909 | (and first-search first-table |
| 900 | ;; Start at beginning of tags file. | 910 | ;; Start at beginning of tags file. |
| 901 | (goto-char (point-min))) | 911 | (goto-char (point-min))) |
| 912 | (or first-table | ||
| 913 | (goto-char (point-min))) | ||
| 914 | |||
| 902 | (setq first-table nil) | 915 | (setq first-table nil) |
| 903 | 916 | ||
| 904 | (setq tags-table-file buffer-file-name) | 917 | (setq tags-table-file buffer-file-name) |
| @@ -920,7 +933,7 @@ See documentation of variable `tags-file-name'." | |||
| 920 | (setq order tag-order)) | 933 | (setq order tag-order)) |
| 921 | ;; We throw out on match, so only get here if there were no matches. | 934 | ;; We throw out on match, so only get here if there were no matches. |
| 922 | (error "No %stags %s %s" (if first-search "" "more ") | 935 | (error "No %stags %s %s" (if first-search "" "more ") |
| 923 | matching pattern)) | 936 | matching pattern))) |
| 924 | 937 | ||
| 925 | ;; Found a tag; extract location info. | 938 | ;; Found a tag; extract location info. |
| 926 | (beginning-of-line) | 939 | (beginning-of-line) |
| @@ -937,7 +950,9 @@ See documentation of variable `tags-file-name'." | |||
| 937 | (set-buffer (find-file-noselect file)) | 950 | (set-buffer (find-file-noselect file)) |
| 938 | (widen) | 951 | (widen) |
| 939 | (push-mark) | 952 | (push-mark) |
| 940 | (funcall goto-func tag-info) | 953 | (if (eq match-type 'tag-filename-match-p) |
| 954 | (goto-char (point-min)) | ||
| 955 | (funcall goto-func tag-info)) | ||
| 941 | 956 | ||
| 942 | ;; Return the buffer where the tag was found. | 957 | ;; Return the buffer where the tag was found. |
| 943 | (current-buffer)))) | 958 | (current-buffer)))) |
| @@ -962,10 +977,12 @@ See documentation of variable `tags-file-name'." | |||
| 962 | (find-tag-regexp-tag-order . (tag-re-match-p)) | 977 | (find-tag-regexp-tag-order . (tag-re-match-p)) |
| 963 | (find-tag-regexp-next-line-after-failure-p . t) | 978 | (find-tag-regexp-next-line-after-failure-p . t) |
| 964 | (find-tag-search-function . search-forward) | 979 | (find-tag-search-function . search-forward) |
| 965 | (find-tag-tag-order . (tag-exact-match-p | 980 | (find-tag-tag-order . (tag-filename-match-p |
| 981 | tag-exact-match-p | ||
| 966 | tag-symbol-match-p | 982 | tag-symbol-match-p |
| 967 | tag-word-match-p | 983 | tag-word-match-p |
| 968 | tag-any-match-p)) | 984 | tag-any-match-p)) |
| 985 | (find-tag-file-order . (tag-filename-match-p)) | ||
| 969 | (find-tag-next-line-after-failure-p . nil) | 986 | (find-tag-next-line-after-failure-p . nil) |
| 970 | (list-tags-function . etags-list-tags) | 987 | (list-tags-function . etags-list-tags) |
| 971 | (tags-apropos-function . etags-tags-apropos) | 988 | (tags-apropos-function . etags-tags-apropos) |
| @@ -1197,6 +1214,11 @@ See documentation of variable `tags-file-name'." | |||
| 1197 | (save-excursion (backward-char (1+ (length tag))) | 1214 | (save-excursion (backward-char (1+ (length tag))) |
| 1198 | (looking-at "\\b")))) | 1215 | (looking-at "\\b")))) |
| 1199 | 1216 | ||
| 1217 | (defun tag-filename-match-p (tag) | ||
| 1218 | (and (looking-at ",") | ||
| 1219 | (save-excursion (backward-char (1+ (length tag))) | ||
| 1220 | (looking-at "\\b")))) | ||
| 1221 | |||
| 1200 | ;; t if point is in a tag line with a tag containing TAG as a substring. | 1222 | ;; t if point is in a tag line with a tag containing TAG as a substring. |
| 1201 | (defun tag-any-match-p (tag) | 1223 | (defun tag-any-match-p (tag) |
| 1202 | (looking-at ".*\177")) | 1224 | (looking-at ".*\177")) |
| @@ -1361,29 +1383,20 @@ See documentation of variable `tags-file-name'." | |||
| 1361 | (tags-loop-continue (or file-list-form t))) | 1383 | (tags-loop-continue (or file-list-form t))) |
| 1362 | 1384 | ||
| 1363 | ;;;###autoload | 1385 | ;;;###autoload |
| 1364 | (defun list-tags (file) | 1386 | (defun list-tags (filename &optional next-match) |
| 1365 | "Display list of tags in file FILE. | 1387 | "Gives the list of functions available in file \"filename\" |
| 1366 | FILE should not contain a directory specification." | 1388 | Searches only in \"tags-file-name\"." |
| 1367 | (interactive (list (completing-read "List tags in file: " | 1389 | (interactive "sFunctions in File: ") |
| 1368 | (save-excursion | 1390 | (let (file-list) |
| 1369 | (visit-tags-table-buffer) | 1391 | (setq file-list (tags-locate-file-in-tags-table filename |
| 1370 | (mapcar 'list | 1392 | (if next-match next-match nil))) |
| 1371 | (mapcar 'file-name-nondirectory | 1393 | (if file-list |
| 1372 | (tags-table-files)))) | 1394 | (if (cdr file-list) |
| 1373 | nil t nil))) | 1395 | (select-tags-matched-file file-list 'extract-pos-and-tag-from-sel |
| 1374 | (with-output-to-temp-buffer "*Tags List*" | 1396 | 'select-file-quit) |
| 1375 | (princ "Tags in file ") | 1397 | (tags-list-functions-in-file (nth 1 (car file-list)) |
| 1376 | (princ file) | 1398 | (nth 2 (car file-list)))) |
| 1377 | (terpri) | 1399 | (message (format "%s not found in tags table" filename))))) |
| 1378 | (save-excursion | ||
| 1379 | (let ((first-time t) | ||
| 1380 | (gotany nil)) | ||
| 1381 | (while (visit-tags-table-buffer (not first-time)) | ||
| 1382 | (setq first-time nil) | ||
| 1383 | (if (funcall list-tags-function file) | ||
| 1384 | (setq gotany t))) | ||
| 1385 | (or gotany | ||
| 1386 | (error "File %s not in current tags tables" file)))))) | ||
| 1387 | 1400 | ||
| 1388 | ;;;###autoload | 1401 | ;;;###autoload |
| 1389 | (defun tags-apropos (regexp) | 1402 | (defun tags-apropos (regexp) |
| @@ -1531,6 +1544,76 @@ for \\[find-tag] (which see)." | |||
| 1531 | 1544 | ||
| 1532 | ;;;###autoload (define-key esc-map "\t" 'complete-tag) | 1545 | ;;;###autoload (define-key esc-map "\t" 'complete-tag) |
| 1533 | 1546 | ||
| 1547 | (defun tags-list-functions-in-file (pos tag-file) | ||
| 1548 | "Lists the functions for the given file. Backend for `list-tags'." | ||
| 1549 | (let ((tag-buf (find-file-noselect tag-file)) | ||
| 1550 | (result-buf (get-buffer-create "*Tags Function List*")) | ||
| 1551 | function | ||
| 1552 | beg | ||
| 1553 | map) | ||
| 1554 | (save-excursion | ||
| 1555 | (set-buffer result-buf) | ||
| 1556 | (erase-buffer) | ||
| 1557 | (set-buffer tag-buf) | ||
| 1558 | (goto-char pos) | ||
| 1559 | (forward-line 1) | ||
| 1560 | (beginning-of-line) | ||
| 1561 | ; C-l marks end of information of a file in TAGS. | ||
| 1562 | (while (and (not (looking-at "^\C-l")) (not (eobp))) | ||
| 1563 | ; skip mere #defines, typedefs and struct definitions | ||
| 1564 | (if (not (or (looking-at "^#define\\s-+[a-zA-Z0-9_]+\\s-+") | ||
| 1565 | (looking-at "^typedef\\s-+") | ||
| 1566 | (looking-at "^\\s-*}"))) | ||
| 1567 | (progn | ||
| 1568 | (setq beg (point)) | ||
| 1569 | (skip-chars-forward "^\C-?(") | ||
| 1570 | (setq function (buffer-substring beg (point))) | ||
| 1571 | (save-excursion | ||
| 1572 | (set-buffer result-buf) | ||
| 1573 | (insert (concat function "\n"))))) | ||
| 1574 | (forward-line 1) | ||
| 1575 | (beginning-of-line))) | ||
| 1576 | (switch-to-buffer "*Tags Function List*") | ||
| 1577 | (goto-char 1) | ||
| 1578 | (set-buffer-modified-p nil) | ||
| 1579 | (setq buffer-read-only t))) | ||
| 1580 | |||
| 1581 | (defun tags-locate-file-in-tags-table (filename first-search) | ||
| 1582 | "This function is used to locate `filename' in `tags-table-list'. | ||
| 1583 | Its internally used by the functions `find-file-from-tags' and | ||
| 1584 | `tags-list-tags-in-file'. If `first-search' is t, search continues from where | ||
| 1585 | it left off last time. Else, its a fresh search." | ||
| 1586 | (let (tag-list current-tags-buffer beg file found-file-list next-tag-file) | ||
| 1587 | (setq tag-list tags-table-list) | ||
| 1588 | (catch 'found-file | ||
| 1589 | (setq found-file-list nil | ||
| 1590 | next-tag-file nil) | ||
| 1591 | (while tag-list | ||
| 1592 | (setq current-tags-buffer (find-file-noselect (car tag-list))) | ||
| 1593 | (save-excursion | ||
| 1594 | (set-buffer current-tags-buffer) | ||
| 1595 | (if (or next-tag-file | ||
| 1596 | (not first-search)) | ||
| 1597 | (goto-char (point-min))) | ||
| 1598 | (if (search-forward filename nil t) | ||
| 1599 | (if (tag-filename-match-p filename) | ||
| 1600 | (progn | ||
| 1601 | (beginning-of-line) | ||
| 1602 | (setq beg (point)) | ||
| 1603 | (skip-chars-forward "^,") | ||
| 1604 | (or (looking-at ",include$") | ||
| 1605 | (setq file (expand-file-name (buffer-substring beg | ||
| 1606 | (point))))) | ||
| 1607 | (if (string-match filename (file-name-nondirectory file)) | ||
| 1608 | (progn | ||
| 1609 | (setq found-file-list (cons (list file (point) | ||
| 1610 | (buffer-file-name)) | ||
| 1611 | found-file-list)) | ||
| 1612 | (throw 'found-file found-file-list)))))) | ||
| 1613 | (setq tag-list (cdr tag-list)) | ||
| 1614 | (setq next-tag-file 't))) | ||
| 1615 | (throw 'found-file found-file-list)))) | ||
| 1616 | |||
| 1534 | (provide 'etags) | 1617 | (provide 'etags) |
| 1535 | 1618 | ||
| 1536 | ;;; etags.el ends here | 1619 | ;;; etags.el ends here |