Since I'm such an igrep fan, I would use it as a building block. From there, these are two simple procedures, and you're done. With this library and these two functions, you only need to:
Mx igrep-tags ^SomeRegexp.*Here RET
Here is the code:
(require 'igrep) (defun igrep-tags (regex) (interactive "sTAGS Regexp: ") (igrep igrep-program regex (tags-file-names))) (defun tags-file-names () (save-excursion (visit-tags-table-buffer) (mapcar (lambda (f) (file-truename f)) (tags-table-files))))
And since the list of files can be very long, and you probably don't care what the list is, you can add these two code snippets that will make the file names invisible after grep completes:
(add-hook 'compilation-finish-functions 'igrep-tags-hide-filenames) (defun igrep-tags-hide-filenames (buffer stat) "hide the filenames b/c they can get long" (save-excursion (set-buffer buffer) (save-match-data (goto-char (point-min)) (if (search-forward (combine-and-quote-strings (tags-file-names)) nil (save-excursion (forward-line 10) (point))) (let ((display-string "..<files from TAGS>..")) (put-text-property (match-beginning 0) (match-end 0) 'invisible t) (put-text-property (match-beginning 0) (match-end 0) 'display display-string))))))
To avoid a very long command line, you can use the following code (which creates a temporary file containing all the file names from the TAGS file and uses this instead):
(defun igrep-tags (regex) (interactive "sTAGS Regexp: ") (let ((igrep-find t) (igrep-use-file-as-containing-files t)) (igrep igrep-program regex nil))) (defvar igrep-use-file-as-containing-files nil) (defadvice igrep-format-find-command (around igrep-format-find-command-use-filename-instead activate) "use the second argument as a file containing filenames" (if igrep-use-file-as-containing-files (progn (with-temp-file (setq igrep-use-file-as-containing-files (make-temp-file "tags-files")) (insert (combine-and-quote-strings (tags-file-names)))) (setq ad-return-value (format "cat %s | xargs -e %s" igrep-use-file-as-containing-files (ad-get-arg 0)))) ad-do-it))
And for those using Emacs 22 or earlier, you will need the program that comes with Emacs 23 (from subr.el )
(defun combine-and-quote-strings (strings &optional separator) "Concatenate the STRINGS, adding the SEPARATOR (default \" \"). This tries to quote the strings to avoid ambiguity such that (split-string-and-unquote (combine-and-quote-strings strs)) == strs Only some SEPARATORs will work properly." (let* ((sep (or separator " ")) (re (concat "[\\\"]" "\\|" (regexp-quote sep)))) (mapconcat (lambda (str) (if (string-match re str) (concat "\"" (replace-regexp-in-string "[\\\"]" "\\\\\\&" str) "\"") str)) strings sep)))
Trey jackson
source share