comparison lisp/progmodes/etags.el @ 91776:01d2b6c9032f

Add many doc strings.
author Richard M. Stallman <rms@gnu.org>
date Mon, 11 Feb 2008 17:35:37 +0000
parents 36aeb7924be6
children 5dee8473f368
comparison
equal deleted inserted replaced
91775:aab40ecbce33 91776:01d2b6c9032f
256 (defvar tags-included-tables-function nil 256 (defvar tags-included-tables-function nil
257 "Function to do the work of `tags-included-tables' (which see).") 257 "Function to do the work of `tags-included-tables' (which see).")
258 (defvar verify-tags-table-function nil 258 (defvar verify-tags-table-function nil
259 "Function to return t if current buffer contains valid tags file.") 259 "Function to return t if current buffer contains valid tags file.")
260 260
261 ;; Initialize the tags table in the current buffer.
262 ;; Returns non-nil if it is a valid tags table. On
263 ;; non-nil return, the tags table state variable are
264 ;; made buffer-local and initialized to nil.
265 (defun initialize-new-tags-table () 261 (defun initialize-new-tags-table ()
262 "Initialize the tags table in the current buffer.
263 Return non-nil if it is a valid tags table, and
264 in that case, also make the tags table state variables
265 buffer-local and set them to nil."
266 (set (make-local-variable 'tags-table-files) nil) 266 (set (make-local-variable 'tags-table-files) nil)
267 (set (make-local-variable 'tags-completion-table) nil) 267 (set (make-local-variable 'tags-completion-table) nil)
268 (set (make-local-variable 'tags-included-tables) nil) 268 (set (make-local-variable 'tags-included-tables) nil)
269 ;; We used to initialize find-tag-marker-ring and tags-location-ring 269 ;; We used to initialize find-tag-marker-ring and tags-location-ring
270 ;; here, to new empty rings. But that is wrong, because those 270 ;; here, to new empty rings. But that is wrong, because those
355 ;; Record the tags-table-list value (and the context of the 355 ;; Record the tags-table-list value (and the context of the
356 ;; current directory) we computed from. 356 ;; current directory) we computed from.
357 (setq tags-table-computed-list-for compute-for 357 (setq tags-table-computed-list-for compute-for
358 tags-table-computed-list (nreverse computed)))))) 358 tags-table-computed-list (nreverse computed))))))
359 359
360 ;; Extend `tags-table-computed-list' to remove the first `t' placeholder.
361 ;; An element of the list that is `t' is a placeholder indicating that the
362 ;; preceding element is a table that has not been read into core and might
363 ;; contain included tables to search. On return, the first placeholder
364 ;; element will be gone and the element before it read into core and its
365 ;; included tables inserted into the list.
366 (defun tags-table-extend-computed-list () 360 (defun tags-table-extend-computed-list ()
361 "Extend `tags-table-computed-list' to remove the first t placeholder.
362
363 An element of the list that is t is a placeholder indicating that the
364 preceding element is a table that has not been read in and might
365 contain included tables to search. This function reads in the first
366 such table and puts its included tables into the list."
367 (let ((list tags-table-computed-list)) 367 (let ((list tags-table-computed-list))
368 (while (not (eq (nth 1 list) t)) 368 (while (not (eq (nth 1 list) t))
369 (setq list (cdr list))) 369 (setq list (cdr list)))
370 (save-excursion 370 (save-excursion
371 (if (tags-verify-table (car list)) 371 (if (tags-verify-table (car list))
396 ;; current list. 396 ;; current list.
397 (setcdr list (nconc computed (cdr (cdr list))))) 397 (setcdr list (nconc computed (cdr (cdr list)))))
398 ;; It was not a valid table, so just remove the following placeholder. 398 ;; It was not a valid table, so just remove the following placeholder.
399 (setcdr list (cdr (cdr list))))))) 399 (setcdr list (cdr (cdr list)))))))
400 400
401 ;; Expand tags table name FILE into a complete file name.
402 (defun tags-expand-table-name (file) 401 (defun tags-expand-table-name (file)
402 "Expand tags table name FILE into a complete file name."
403 (setq file (expand-file-name file)) 403 (setq file (expand-file-name file))
404 (if (file-directory-p file) 404 (if (file-directory-p file)
405 (expand-file-name "TAGS" file) 405 (expand-file-name "TAGS" file)
406 file)) 406 file))
407 407
408 ;; Like member, but comparison is done after tags-expand-table-name on both 408 ;; Like member, but comparison is done after tags-expand-table-name on both
409 ;; sides and elements of LIST that are t are skipped. 409 ;; sides and elements of LIST that are t are skipped.
410 (defun tags-table-list-member (file list) 410 (defun tags-table-list-member (file list)
411 "Like (member FILE LIST) after applying `tags-expand-table-name'.
412 More precisely, apply `tags-expand-table-name' to FILE
413 and each element of LIST, returning the link whose car is the first match.
414 If an element of LIST is t, ignore it."
411 (setq file (tags-expand-table-name file)) 415 (setq file (tags-expand-table-name file))
412 (while (and list 416 (while (and list
413 (or (eq (car list) t) 417 (or (eq (car list) t)
414 (not (string= file (tags-expand-table-name (car list)))))) 418 (not (string= file (tags-expand-table-name (car list))))))
415 (setq list (cdr list))) 419 (setq list (cdr list)))
462 ;; does). Return the name of the first table table listing THIS-FILE; if 466 ;; does). Return the name of the first table table listing THIS-FILE; if
463 ;; the table is one included by another table, it is the master table that 467 ;; the table is one included by another table, it is the master table that
464 ;; we return. If CORE-ONLY is non-nil, check only tags tables that are 468 ;; we return. If CORE-ONLY is non-nil, check only tags tables that are
465 ;; already in buffers--don't visit any new files. 469 ;; already in buffers--don't visit any new files.
466 (defun tags-table-including (this-file core-only) 470 (defun tags-table-including (this-file core-only)
471 "Search current tags tables for tags for THIS-FILE.
472 Subroutine of `visit-tags-table-buffer'.
473 Looks for a tags table that has such tags or that includes a table
474 that has them. Returns the name of the first such table.
475 Non-nil CORE-ONLY means check only tags tables that are already in
476 buffers. Nil CORE-ONLY is ignored."
467 (let ((tables tags-table-computed-list) 477 (let ((tables tags-table-computed-list)
468 (found nil)) 478 (found nil))
469 ;; Loop over the list, looking for a table containing tags for THIS-FILE. 479 ;; Loop over the list, looking for a table containing tags for THIS-FILE.
470 (while (and (not found) 480 (while (and (not found)
471 tables) 481 tables)
507 ;; The last element we found in the computed list before FOUND 517 ;; The last element we found in the computed list before FOUND
508 ;; that appears in the user's list will be the table that 518 ;; that appears in the user's list will be the table that
509 ;; included the one we found. 519 ;; included the one we found.
510 could-be)))) 520 could-be))))
511 521
512 ;; Subroutine of visit-tags-table-buffer. Move tags-table-list-pointer
513 ;; along and set tags-file-name. Returns nil when out of tables.
514 (defun tags-next-table () 522 (defun tags-next-table ()
523 "Move `tags-table-list-pointer' along and set `tags-file-name'.
524 Subroutine of `visit-tags-table-buffer'.\
525 Returns nil when out of tables."
515 ;; If there is a placeholder element next, compute the list to replace it. 526 ;; If there is a placeholder element next, compute the list to replace it.
516 (while (eq (nth 1 tags-table-list-pointer) t) 527 (while (eq (nth 1 tags-table-list-pointer) t)
517 (tags-table-extend-computed-list)) 528 (tags-table-extend-computed-list))
518 529
519 ;; Go to the next table in the list. 530 ;; Go to the next table in the list.
670 (setq tags-table-set-list 681 (setq tags-table-set-list
671 (cons tags-table-list 682 (cons tags-table-list
672 tags-table-set-list))) 683 tags-table-set-list)))
673 ;; Clear out buffers holding old tables. 684 ;; Clear out buffers holding old tables.
674 (dolist (table tags-table-list) 685 (dolist (table tags-table-list)
675 ;; The list can contain items `t'. 686 ;; The list can contain items t.
676 (if (stringp table) 687 (if (stringp table)
677 (let ((buffer (find-buffer-visiting table))) 688 (let ((buffer (find-buffer-visiting table)))
678 (if buffer 689 (if buffer
679 (kill-buffer buffer))))) 690 (kill-buffer buffer)))))
680 (setq tags-table-list (list local-tags-file-name)))) 691 (setq tags-table-list (list local-tags-file-name))))
740 "Return a list of tags tables included by the current table. 751 "Return a list of tags tables included by the current table.
741 Assumes the tags table is the current buffer." 752 Assumes the tags table is the current buffer."
742 (or tags-included-tables 753 (or tags-included-tables
743 (setq tags-included-tables (funcall tags-included-tables-function)))) 754 (setq tags-included-tables (funcall tags-included-tables-function))))
744 755
745 ;; Build tags-completion-table on demand. The single current tags table
746 ;; and its included tags tables (and their included tables, etc.) have
747 ;; their tags included in the completion table.
748 (defun tags-completion-table () 756 (defun tags-completion-table ()
757 "Build `tags-completion-table' on demand.
758 The tags included in the completion table are those in the current
759 tags table and its (recursively) included tags tables."
749 (or tags-completion-table 760 (or tags-completion-table
750 ;; No cached value for this buffer. 761 ;; No cached value for this buffer.
751 (condition-case () 762 (condition-case ()
752 (let (current-table combined-table) 763 (let (current-table combined-table)
753 (message "Making tags completion table for %s..." buffer-file-name) 764 (message "Making tags completion table for %s..." buffer-file-name)
767 ;; Cache the result a buffer-local variable. 778 ;; Cache the result a buffer-local variable.
768 (setq tags-completion-table combined-table)) 779 (setq tags-completion-table combined-table))
769 (quit (message "Tags completion table construction aborted.") 780 (quit (message "Tags completion table construction aborted.")
770 (setq tags-completion-table nil))))) 781 (setq tags-completion-table nil)))))
771 782
772 ;; Completion function for tags. Does normal try-completion,
773 ;; but builds tags-completion-table on demand.
774 (defun tags-complete-tag (string predicate what) 783 (defun tags-complete-tag (string predicate what)
784 "Completion function for tags.
785 Does normal `try-completion', but builds `tags-completion-table' on
786 demand."
775 (save-excursion 787 (save-excursion
776 ;; If we need to ask for the tag table, allow that. 788 ;; If we need to ask for the tag table, allow that.
777 (let ((enable-recursive-minibuffers t)) 789 (let ((enable-recursive-minibuffers t))
778 (visit-tags-table-buffer)) 790 (visit-tags-table-buffer))
779 (if (eq what t) 791 (if (eq what t)
780 (all-completions string (tags-completion-table) predicate) 792 (all-completions string (tags-completion-table) predicate)
781 (try-completion string (tags-completion-table) predicate)))) 793 (try-completion string (tags-completion-table) predicate))))
782 794
783 ;; Read a tag name from the minibuffer with defaulting and completion.
784 (defun find-tag-tag (string) 795 (defun find-tag-tag (string)
796 "Read a tag name, with defaulting and completion."
785 (let* ((completion-ignore-case (if (memq tags-case-fold-search '(t nil)) 797 (let* ((completion-ignore-case (if (memq tags-case-fold-search '(t nil))
786 tags-case-fold-search 798 tags-case-fold-search
787 case-fold-search)) 799 case-fold-search))
788 (default (funcall (or find-tag-default-function 800 (default (funcall (or find-tag-default-function
789 (get major-mode 'find-tag-default-function) 801 (get major-mode 'find-tag-default-function)
800 spec))) 812 spec)))
801 813
802 (defvar last-tag nil 814 (defvar last-tag nil
803 "Last tag found by \\[find-tag].") 815 "Last tag found by \\[find-tag].")
804 816
805 ;; Get interactive args for find-tag{-noselect,-other-window,-regexp}.
806 (defun find-tag-interactive (prompt &optional no-default) 817 (defun find-tag-interactive (prompt &optional no-default)
818 "Get interactive arguments for tag functions.
819 The functions using this are `find-tag-noselect',
820 `find-tag-other-window', and `find-tag-regexp'."
807 (if (and current-prefix-arg last-tag) 821 (if (and current-prefix-arg last-tag)
808 (list nil (if (< (prefix-numeric-value current-prefix-arg) 0) 822 (list nil (if (< (prefix-numeric-value current-prefix-arg) 0)
809 '- 823 '-
810 t)) 824 t))
811 (list (if no-default 825 (list (if no-default
812 (read-string prompt) 826 (read-string prompt)
813 (find-tag-tag prompt))))) 827 (find-tag-tag prompt)))))
814 828
815 (defvar find-tag-history nil) 829 (defvar find-tag-history nil) ; Doc string?
816 830
817 ;; Dynamic bondage: 831 ;; Dynamic bondage:
818 (eval-when-compile 832 (eval-when-compile
819 (defvar etags-case-fold-search) 833 (defvar etags-case-fold-search)
820 (defvar etags-syntax-table)) 834 (defvar etags-syntax-table))
1026 (switch-to-buffer (or (marker-buffer marker) 1040 (switch-to-buffer (or (marker-buffer marker)
1027 (error "The marked buffer has been deleted"))) 1041 (error "The marked buffer has been deleted")))
1028 (goto-char (marker-position marker)) 1042 (goto-char (marker-position marker))
1029 (set-marker marker nil nil))) 1043 (set-marker marker nil nil)))
1030 1044
1031 ;; Internal tag finding function. 1045 (defvar tag-lines-already-matched nil
1032 1046 "Matches remembered between calls.") ; Doc string: calls to what?
1033 ;; PATTERN is a string to pass to second arg SEARCH-FORWARD-FUNC, and to
1034 ;; any member of the function list ORDER (third arg). If ORDER is nil,
1035 ;; use saved state to continue a previous search.
1036
1037 ;; Fourth arg NEXT-LINE-AFTER-FAILURE-P is non-nil if after a failed match,
1038 ;; point should be moved to the next line.
1039
1040 ;; Fifth arg MATCHING is a string, an English '-ing' word, to be used in
1041 ;; an error message.
1042
1043 ;; Algorithm is as follows. For each qualifier-func in ORDER, go to
1044 ;; beginning of tags file, and perform inner loop: for each naive match for
1045 ;; PATTERN found using SEARCH-FORWARD-FUNC, qualify the naive match using
1046 ;; qualifier-func. If it qualifies, go to the specified line in the
1047 ;; specified source file and return. Qualified matches are remembered to
1048 ;; avoid repetition. State is saved so that the loop can be continued.
1049
1050 (defvar tag-lines-already-matched nil) ;matches remembered here between calls
1051 1047
1052 (defun find-tag-in-order (pattern 1048 (defun find-tag-in-order (pattern
1053 search-forward-func 1049 search-forward-func
1054 order 1050 order
1055 next-line-after-failure-p 1051 next-line-after-failure-p
1056 matching 1052 matching
1057 first-search) 1053 first-search)
1054 "Internal tag-finding function.
1055 PATTERN is a string to pass to arg SEARCH-FORWARD-FUNC, and to any
1056 member of the function list ORDER. If ORDER is nil, use saved state
1057 to continue a previous search.
1058
1059 Arg NEXT-LINE-AFTER-FAILURE-P is non-nil if after a failed match,
1060 point should be moved to the next line.
1061
1062 Arg MATCHING is a string, an English `-ing' word, to be used in an
1063 error message."
1064 ;; Algorithm is as follows:
1065 ;; For each qualifier-func in ORDER, go to beginning of tags file, and
1066 ;; perform inner loop: for each naive match for PATTERN found using
1067 ;; SEARCH-FORWARD-FUNC, qualify the naive match using qualifier-func. If
1068 ;; it qualifies, go to the specified line in the specified source file
1069 ;; and return. Qualified matches are remembered to avoid repetition.
1070 ;; State is saved so that the loop can be continued.
1058 (let (file ;name of file containing tag 1071 (let (file ;name of file containing tag
1059 tag-info ;where to find the tag in FILE 1072 tag-info ;where to find the tag in FILE
1060 (first-table t) 1073 (first-table t)
1061 (tag-order order) 1074 (tag-order order)
1062 (match-marker (make-marker)) 1075 (match-marker (make-marker))
1145 1158
1146 ;; Return the buffer where the tag was found. 1159 ;; Return the buffer where the tag was found.
1147 (current-buffer)))) 1160 (current-buffer))))
1148 1161
1149 (defun tag-find-file-of-tag-noselect (file) 1162 (defun tag-find-file-of-tag-noselect (file)
1150 ;; Find the right line in the specified file. 1163 "Find the right line in the specified FILE."
1151 ;; If we are interested in compressed-files, 1164 ;; If interested in compressed-files, search files with extensions.
1152 ;; we search files with extensions. 1165 ;; Otherwise, search only the real file.
1153 ;; otherwise only the real file.
1154 (let* ((buffer-search-extensions (if (featurep 'jka-compr) 1166 (let* ((buffer-search-extensions (if (featurep 'jka-compr)
1155 tags-compression-info-list 1167 tags-compression-info-list
1156 '(""))) 1168 '("")))
1157 the-buffer 1169 the-buffer
1158 (file-search-extensions buffer-search-extensions)) 1170 (file-search-extensions buffer-search-extensions))
1178 (if (featurep 'jka-compr) 1190 (if (featurep 'jka-compr)
1179 (error "File %s (with or without extensions %s) not found" file tags-compression-info-list) 1191 (error "File %s (with or without extensions %s) not found" file tags-compression-info-list)
1180 (error "File %s not found" file)) 1192 (error "File %s not found" file))
1181 (set-buffer the-buffer)))) 1193 (set-buffer the-buffer))))
1182 1194
1183 (defun tag-find-file-of-tag (file) 1195 (defun tag-find-file-of-tag (file) ; Doc string?
1184 (let ((buf (tag-find-file-of-tag-noselect file))) 1196 (let ((buf (tag-find-file-of-tag-noselect file)))
1185 (condition-case nil 1197 (condition-case nil
1186 (switch-to-buffer buf) 1198 (switch-to-buffer buf)
1187 (error (pop-to-buffer buf))))) 1199 (error (pop-to-buffer buf)))))
1188 1200
1189 ;; `etags' TAGS file format support. 1201 ;; `etags' TAGS file format support.
1190 1202
1191 ;; If the current buffer is a valid etags TAGS file, give it local values of
1192 ;; the tags table format variables, and return non-nil.
1193 (defun etags-recognize-tags-table () 1203 (defun etags-recognize-tags-table ()
1204 "If `etags-verify-tags-table', make buffer-local format variables.
1205 If current buffer is a valid etags TAGS file, then give it
1206 buffer-local values of tags table format variables."
1194 (and (etags-verify-tags-table) 1207 (and (etags-verify-tags-table)
1195 ;; It is annoying to flash messages on the screen briefly, 1208 ;; It is annoying to flash messages on the screen briefly,
1196 ;; and this message is not useful. -- rms 1209 ;; and this message is not useful. -- rms
1197 ;; (message "%s is an `etags' TAGS file" buffer-file-name) 1210 ;; (message "%s is an `etags' TAGS file" buffer-file-name)
1198 (mapc (lambda (elt) (set (make-local-variable (car elt)) (cdr elt))) 1211 (mapc (lambda (elt) (set (make-local-variable (car elt)) (cdr elt)))
1223 (defun etags-verify-tags-table () 1236 (defun etags-verify-tags-table ()
1224 "Return non-nil if the current buffer is a valid etags TAGS file." 1237 "Return non-nil if the current buffer is a valid etags TAGS file."
1225 ;; Use eq instead of = in case char-after returns nil. 1238 ;; Use eq instead of = in case char-after returns nil.
1226 (eq (char-after (point-min)) ?\f)) 1239 (eq (char-after (point-min)) ?\f))
1227 1240
1228 (defun etags-file-of-tag (&optional relative) 1241 (defun etags-file-of-tag (&optional relative) ; Doc string?
1229 (save-excursion 1242 (save-excursion
1230 (re-search-backward "\f\n\\([^\n]+\\),[0-9]*\n") 1243 (re-search-backward "\f\n\\([^\n]+\\),[0-9]*\n")
1231 (let ((str (buffer-substring (match-beginning 1) (match-end 1)))) 1244 (let ((str (buffer-substring (match-beginning 1) (match-end 1))))
1232 (if relative 1245 (if relative
1233 str 1246 str
1234 (expand-file-name str 1247 (expand-file-name str
1235 (file-truename default-directory)))))) 1248 (file-truename default-directory))))))
1236 1249
1237 1250
1238 (defun etags-tags-completion-table () 1251 (defun etags-tags-completion-table () ; Doc string?
1239 (let ((table (make-vector 511 0)) 1252 (let ((table (make-vector 511 0))
1240 (progress-reporter 1253 (progress-reporter
1241 (make-progress-reporter 1254 (make-progress-reporter
1242 (format "Making tags completion table for %s..." buffer-file-name) 1255 (format "Making tags completion table for %s..." buffer-file-name)
1243 (point-min) (point-max)))) 1256 (point-min) (point-max))))
1263 (buffer-substring (match-beginning 3) (match-end 3))) 1276 (buffer-substring (match-beginning 3) (match-end 3)))
1264 (progress-reporter-update progress-reporter (point))) 1277 (progress-reporter-update progress-reporter (point)))
1265 table))) 1278 table)))
1266 table)) 1279 table))
1267 1280
1268 (defun etags-snarf-tag (&optional use-explicit) 1281 (defun etags-snarf-tag (&optional use-explicit) ; Doc string?
1269 (let (tag-text line startpos explicit-start) 1282 (let (tag-text line startpos explicit-start)
1270 (if (save-excursion 1283 (if (save-excursion
1271 (forward-line -1) 1284 (forward-line -1)
1272 (looking-at "\f\n")) 1285 (looking-at "\f\n"))
1273 ;; The match was for a source file name, not any tag within a file. 1286 ;; The match was for a source file name, not any tag within a file.
1303 (point))))))) 1316 (point)))))))
1304 ;; Leave point on the next line of the tags file. 1317 ;; Leave point on the next line of the tags file.
1305 (forward-line 1) 1318 (forward-line 1)
1306 (cons tag-text (cons line startpos)))) 1319 (cons tag-text (cons line startpos))))
1307 1320
1308 ;; TAG-INFO is a cons (TEXT LINE . POSITION) where TEXT is the initial part
1309 ;; of a line containing the tag and POSITION is the character position of
1310 ;; TEXT within the file (starting from 1); LINE is the line number. If
1311 ;; TEXT is t, it means the tag refers to exactly LINE or POSITION
1312 ;; (whichever is present, LINE having preference, no searching. Either
1313 ;; LINE or POSITION may be nil; POSITION is used if present. If the tag
1314 ;; isn't exactly at the given position then look around that position using
1315 ;; a search window which expands until it hits the start of file.
1316 (defun etags-goto-tag-location (tag-info) 1321 (defun etags-goto-tag-location (tag-info)
1322 "Go to location of tag specified by TAG-INFO.
1323 TAG-INFO is a cons (TEXT LINE . POSITION).
1324 TEXT is the initial part of a line containing the tag.
1325 LINE is the line number.
1326 POSITION is the (one-based) char position of TEXT within the file.
1327
1328 If TEXT is t, it means the tag refers to exactly LINE or POSITION,
1329 whichever is present, LINE having preference, no searching.
1330 Either LINE or POSITION can be nil. POSITION is used if present.
1331
1332 If the tag isn't exactly at the given position, then look near that
1333 position using a search window that expands progressively until it
1334 hits the start of file."
1317 (let ((startpos (cdr (cdr tag-info))) 1335 (let ((startpos (cdr (cdr tag-info)))
1318 (line (car (cdr tag-info))) 1336 (line (car (cdr tag-info)))
1319 offset found pat) 1337 offset found pat)
1320 (if (eq (car tag-info) t) 1338 (if (eq (car tag-info) t)
1321 ;; Direct file tag. 1339 ;; Direct file tag.
1360 (and (eq selective-display t) 1378 (and (eq selective-display t)
1361 (looking-at "\^m") 1379 (looking-at "\^m")
1362 (forward-char 1)) 1380 (forward-char 1))
1363 (beginning-of-line))) 1381 (beginning-of-line)))
1364 1382
1365 (defun etags-list-tags (file) 1383 (defun etags-list-tags (file) ; Doc string?
1366 (goto-char (point-min)) 1384 (goto-char (point-min))
1367 (when (re-search-forward (concat "\f\n" "\\(" file "\\)" ",") nil t) 1385 (when (re-search-forward (concat "\f\n" "\\(" file "\\)" ",") nil t)
1368 (let ((path (save-excursion (forward-line 1) (file-of-tag))) 1386 (let ((path (save-excursion (forward-line 1) (file-of-tag)))
1369 ;; Get the local value in the tags table 1387 ;; Get the local value in the tags table
1370 ;; buffer before switching buffers. 1388 ;; buffer before switching buffers.
1433 (mapatoms ins-symb symbs) 1451 (mapatoms ins-symb symbs)
1434 (dolist (sy symbs) 1452 (dolist (sy symbs)
1435 (funcall ins-symb (car sy)))) 1453 (funcall ins-symb (car sy))))
1436 (sort-lines nil beg (point)))))) 1454 (sort-lines nil beg (point))))))
1437 1455
1438 (defun etags-tags-apropos (string) 1456 (defun etags-tags-apropos (string) ; Doc string?
1439 (when tags-apropos-verbose 1457 (when tags-apropos-verbose
1440 (princ "Tags in file `") 1458 (princ "Tags in file `")
1441 (tags-with-face 'highlight (princ buffer-file-name)) 1459 (tags-with-face 'highlight (princ buffer-file-name))
1442 (princ "':\n\n")) 1460 (princ "':\n\n"))
1443 (goto-char (point-min)) 1461 (goto-char (point-min))
1494 (terpri) 1512 (terpri)
1495 (forward-line 1)) 1513 (forward-line 1))
1496 (message nil)) 1514 (message nil))
1497 (when tags-apropos-verbose (princ "\n"))) 1515 (when tags-apropos-verbose (princ "\n")))
1498 1516
1499 (defun etags-tags-table-files () 1517 (defun etags-tags-table-files () ; Doc string?
1500 (let ((files nil) 1518 (let ((files nil)
1501 beg) 1519 beg)
1502 (goto-char (point-min)) 1520 (goto-char (point-min))
1503 (while (search-forward "\f\n" nil t) 1521 (while (search-forward "\f\n" nil t)
1504 (setq beg (point)) 1522 (setq beg (point))
1506 (skip-chars-backward "^," beg) 1524 (skip-chars-backward "^," beg)
1507 (or (looking-at "include$") 1525 (or (looking-at "include$")
1508 (setq files (cons (buffer-substring beg (1- (point))) files)))) 1526 (setq files (cons (buffer-substring beg (1- (point))) files))))
1509 (nreverse files))) 1527 (nreverse files)))
1510 1528
1511 (defun etags-tags-included-tables () 1529 (defun etags-tags-included-tables () ; Doc string?
1512 (let ((files nil) 1530 (let ((files nil)
1513 beg) 1531 beg)
1514 (goto-char (point-min)) 1532 (goto-char (point-min))
1515 (while (search-forward "\f\n" nil t) 1533 (while (search-forward "\f\n" nil t)
1516 (setq beg (point)) 1534 (setq beg (point))
1522 files)))) 1540 files))))
1523 (nreverse files))) 1541 (nreverse files)))
1524 1542
1525 ;; Empty tags file support. 1543 ;; Empty tags file support.
1526 1544
1527 ;; Recognize an empty file and give it local values of the tags table format
1528 ;; variables which do nothing.
1529 (defun tags-recognize-empty-tags-table () 1545 (defun tags-recognize-empty-tags-table ()
1546 "Return non-nil if current buffer is empty.
1547 If empty, make buffer-local values of the tags table format variables
1548 that do nothing."
1530 (and (zerop (buffer-size)) 1549 (and (zerop (buffer-size))
1531 (mapc (lambda (sym) (set (make-local-variable sym) 'ignore)) 1550 (mapc (lambda (sym) (set (make-local-variable sym) 'ignore))
1532 '(tags-table-files-function 1551 '(tags-table-files-function
1533 tags-completion-table-function 1552 tags-completion-table-function
1534 find-tag-regexp-search-function 1553 find-tag-regexp-search-function
1558 ;;(put 'tags-with-syntax 'edebug-form-spec '(&rest form)) 1577 ;;(put 'tags-with-syntax 'edebug-form-spec '(&rest form))
1559 1578
1560 ;; exact file name match, i.e. searched tag must match complete file 1579 ;; exact file name match, i.e. searched tag must match complete file
1561 ;; name including directories parts if there are some. 1580 ;; name including directories parts if there are some.
1562 (defun tag-exact-file-name-match-p (tag) 1581 (defun tag-exact-file-name-match-p (tag)
1582 "Return non-nil if TAG matches complete file name.
1583 Any directory part of the file name is also matched."
1563 (and (looking-at ",[0-9\n]") 1584 (and (looking-at ",[0-9\n]")
1564 (save-excursion (backward-char (+ 2 (length tag))) 1585 (save-excursion (backward-char (+ 2 (length tag)))
1565 (looking-at "\f\n")))) 1586 (looking-at "\f\n"))))
1587
1566 ;; file name match as above, but searched tag must match the file 1588 ;; file name match as above, but searched tag must match the file
1567 ;; name not including the directories if there are some. 1589 ;; name not including the directories if there are some.
1568 (defun tag-file-name-match-p (tag) 1590 (defun tag-file-name-match-p (tag)
1591 "Return non-nil if TAG matches file name, excluding directory part."
1569 (and (looking-at ",[0-9\n]") 1592 (and (looking-at ",[0-9\n]")
1570 (save-excursion (backward-char (1+ (length tag))) 1593 (save-excursion (backward-char (1+ (length tag)))
1571 (looking-at "/")))) 1594 (looking-at "/"))))
1595
1572 ;; this / to detect we are after a directory separator is ok for unix, 1596 ;; this / to detect we are after a directory separator is ok for unix,
1573 ;; is there a variable that contains the regexp for directory separator 1597 ;; is there a variable that contains the regexp for directory separator
1574 ;; on whatever operating system ? 1598 ;; on whatever operating system ?
1575 ;; Looks like ms-win will lose here :). 1599 ;; Looks like ms-win will lose here :).
1576 1600
1577 ;; t if point is at a tag line that matches TAG exactly. 1601 ;; t if point is at a tag line that matches TAG exactly.
1578 ;; point should be just after a string that matches TAG. 1602 ;; point should be just after a string that matches TAG.
1579 (defun tag-exact-match-p (tag) 1603 (defun tag-exact-match-p (tag)
1604 "Return non-nil if current tag line matches TAG exactly.
1605 Point should be just after a string that matches TAG."
1580 ;; The match is really exact if there is an explicit tag name. 1606 ;; The match is really exact if there is an explicit tag name.
1581 (or (and (eq (char-after (point)) ?\001) 1607 (or (and (eq (char-after (point)) ?\001)
1582 (eq (char-after (- (point) (length tag) 1)) ?\177)) 1608 (eq (char-after (- (point) (length tag) 1)) ?\177))
1583 ;; We are not on the explicit tag name, but perhaps it follows. 1609 ;; We are not on the explicit tag name, but perhaps it follows.
1584 (looking-at (concat "[^\177\n]*\177" (regexp-quote tag) "\001")))) 1610 (looking-at (concat "[^\177\n]*\177" (regexp-quote tag) "\001"))))
1585 1611
1586 ;; t if point is at a tag line that has an implicit name. 1612 ;; t if point is at a tag line that has an implicit name.
1587 ;; point should be just after a string that matches TAG. 1613 ;; point should be just after a string that matches TAG.
1588 (defun tag-implicit-name-match-p (tag) 1614 (defun tag-implicit-name-match-p (tag)
1615 "Return non-nil if current tag line has an implicit name.
1616 Point should be just after a string that matches TAG."
1589 ;; Look at the comment of the make_tag function in lib-src/etags.c for 1617 ;; Look at the comment of the make_tag function in lib-src/etags.c for
1590 ;; a textual description of the four rules. 1618 ;; a textual description of the four rules.
1591 (and (string-match "^[^ \t()=,;]+$" tag) ;rule #1 1619 (and (string-match "^[^ \t()=,;]+$" tag) ;rule #1
1592 (looking-at "[ \t()=,;]?\177") ;rules #2 and #4 1620 (looking-at "[ \t()=,;]?\177") ;rules #2 and #4
1593 (save-excursion 1621 (save-excursion
1595 (looking-at "[\n \t()=,;]")))) ;rule #3 1623 (looking-at "[\n \t()=,;]")))) ;rule #3
1596 1624
1597 ;; t if point is at a tag line that matches TAG as a symbol. 1625 ;; t if point is at a tag line that matches TAG as a symbol.
1598 ;; point should be just after a string that matches TAG. 1626 ;; point should be just after a string that matches TAG.
1599 (defun tag-symbol-match-p (tag) 1627 (defun tag-symbol-match-p (tag)
1628 "Return non-nil if current tag line matches TAG as a symbol.
1629 Point should be just after a string that matches TAG."
1600 (and (looking-at "\\Sw.*\177") (looking-at "\\S_.*\177") 1630 (and (looking-at "\\Sw.*\177") (looking-at "\\S_.*\177")
1601 (save-excursion 1631 (save-excursion
1602 (backward-char (1+ (length tag))) 1632 (backward-char (1+ (length tag)))
1603 (and (looking-at "\\Sw") (looking-at "\\S_"))))) 1633 (and (looking-at "\\Sw") (looking-at "\\S_")))))
1604 1634
1605 ;; t if point is at a tag line that matches TAG as a word. 1635 ;; t if point is at a tag line that matches TAG as a word.
1606 ;; point should be just after a string that matches TAG. 1636 ;; point should be just after a string that matches TAG.
1607 (defun tag-word-match-p (tag) 1637 (defun tag-word-match-p (tag)
1638 "Return non-nil if current tag line matches TAG as a word.
1639 Point should be just after a string that matches TAG."
1608 (and (looking-at "\\b.*\177") 1640 (and (looking-at "\\b.*\177")
1609 (save-excursion (backward-char (length tag)) 1641 (save-excursion (backward-char (length tag))
1610 (looking-at "\\b")))) 1642 (looking-at "\\b"))))
1611 1643
1612 ;; partial file name match, i.e. searched tag must match a substring 1644 ;; partial file name match, i.e. searched tag must match a substring
1613 ;; of the file name (potentially including a directory separator). 1645 ;; of the file name (potentially including a directory separator).
1614 (defun tag-partial-file-name-match-p (tag) 1646 (defun tag-partial-file-name-match-p (tag)
1647 "Return non-nil if current tag matches file name.
1648 This is a substring match, and it can include directory separators.
1649 Point should be just after a string that matches TAG."
1615 (and (looking-at ".*,[0-9\n]") 1650 (and (looking-at ".*,[0-9\n]")
1616 (save-excursion (beginning-of-line) 1651 (save-excursion (beginning-of-line)
1617 (backward-char 2) 1652 (backward-char 2)
1618 (looking-at "\f\n")))) 1653 (looking-at "\f\n"))))
1619 1654
1620 ;; t if point is in a tag line with a tag containing TAG as a substring. 1655 ;; t if point is in a tag line with a tag containing TAG as a substring.
1621 (defun tag-any-match-p (tag) 1656 (defun tag-any-match-p (tag)
1657 "Return non-nil if current tag line contains TAG as a substring."
1622 (looking-at ".*\177")) 1658 (looking-at ".*\177"))
1623 1659
1624 ;; t if point is at a tag line that matches RE as a regexp. 1660 ;; t if point is at a tag line that matches RE as a regexp.
1625 (defun tag-re-match-p (re) 1661 (defun tag-re-match-p (re)
1662 "Return non-nil if current tag line matches regexp RE."
1626 (save-excursion 1663 (save-excursion
1627 (beginning-of-line) 1664 (beginning-of-line)
1628 (let ((bol (point))) 1665 (let ((bol (point)))
1629 (and (search-forward "\177" (save-excursion (end-of-line) (point)) t) 1666 (and (search-forward "\177" (save-excursion (end-of-line) (point)) t)
1630 (re-search-backward re bol t))))) 1667 (re-search-backward re bol t)))))
1843 ;; will see it. 1880 ;; will see it.
1844 (goto-char (match-beginning 0)))) 1881 (goto-char (match-beginning 0))))
1845 tags-loop-operate `(perform-replace ',from ',to t t ',delimited)) 1882 tags-loop-operate `(perform-replace ',from ',to t t ',delimited))
1846 (tags-loop-continue (or file-list-form t))) 1883 (tags-loop-continue (or file-list-form t)))
1847 1884
1848 (defun tags-complete-tags-table-file (string predicate what) 1885 (defun tags-complete-tags-table-file (string predicate what) ; Doc string?
1849 (save-excursion 1886 (save-excursion
1850 ;; If we need to ask for the tag table, allow that. 1887 ;; If we need to ask for the tag table, allow that.
1851 (let ((enable-recursive-minibuffers t)) 1888 (let ((enable-recursive-minibuffers t))
1852 (visit-tags-table-buffer)) 1889 (visit-tags-table-buffer))
1853 (if (eq what t) 1890 (if (eq what t)
1964 (goto-char desired-point)) 2001 (goto-char desired-point))
1965 (set-window-start (selected-window) 1 t)) 2002 (set-window-start (selected-window) 1 t))
1966 (set-buffer-modified-p nil) 2003 (set-buffer-modified-p nil)
1967 (select-tags-table-mode)) 2004 (select-tags-table-mode))
1968 2005
1969 (defvar select-tags-table-mode-map 2006 (defvar select-tags-table-mode-map ; Doc string?
1970 (let ((map (make-sparse-keymap))) 2007 (let ((map (make-sparse-keymap)))
1971 (set-keymap-parent map button-buffer-map) 2008 (set-keymap-parent map button-buffer-map)
1972 (define-key map "t" 'push-button) 2009 (define-key map "t" 'push-button)
1973 (define-key map " " 'next-line) 2010 (define-key map " " 'next-line)
1974 (define-key map "\^?" 'previous-line) 2011 (define-key map "\^?" 'previous-line)