Help writing emacs lisp for emacs etags search

I am looking for some help in developing what, in my opinion, should be an easy program.

I need something similar to the emacs-search-search command, but I want to collect all the search results in a buffer. (I want to see all the results of M -,)

I think this python-style pseudo code should work, but I have no idea how to do this in emacs lisp? Any help would be greatly appreciated.

def myTagsGrep(searchValue): for aFile in the tag list: result = grep aFile seachValue if len(result) > 0: print aFile # to the buffer print result # to the buffer 

I would like to be able to view the buffer with the same function tags as apropos.

Note that a similar question was asked before: Is there a way to get the emacs tag-search command to print all the results to the buffer?

+6
emacs lisp elisp
source share
3 answers

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))) 
+1
source share

Here is the code that I use to create a tag system for my personal notes. It uses bookmarks and treats each word in a bookmark as a single tag. This is not exactly what you are looking for, but you can start.

The first few functions are probably already implemented in emacs, but I wrote my own for reasons that I no longer recall.

 ;; FILTER keeps only elements of li for which pred returns true (defun filter (pred li) (let (acc) (dolist (elem li) (if (funcall pred elem) (setq acc (cons elem acc)))) (reverse acc))) (defun string-match-all-p (str li) (if li (if (string-match-p (car li) str) (string-match-all-p str (cdr li)) nil) t)) ;;bookmarks as tags (defun lookup-bookmark-tags (tagstring) (interactive "s") (let ((taglist (split-string tagstring " "))) (let ((bookmark-alist (filter (lambda (elem) (string-match-all-p (car elem) taglist)) bookmark-alist))) (call-interactively 'list-bookmarks)))) 

Then I bind the behavior of "tagging" to the key (F11) and "referring" to another (F12).

 (global-set-key [f11] 'bookmark-set) (global-set-key [f12] 'lookup-bookmark-tags)) 

Hope this is helpful for you.

+1
source share

Is this what you want:

http://www.emacswiki.org/emacs/Icicles_-_Emacs_Tags_Enhancements#icicle-tags-search

This is the document line for icicle-tags-search :

  Search all source files listed in tags tables for matches for REGEXP.
     You are prompted for the REGEXP to match.  Enter REGEXP with `RET '.
     You do not need `M-, '- you see all matches as search hits to visit.

     All tags in a tags file are used, including duplicate tags from the
     same or different source files.

     By default, all tags files are used, but if you provide a prefix
     argument then only the current tag table is used.

     If your TAGS file references source files that no longer exist, those
     files are listed.  In that case, you might want to update your TAGS
     file.


     You can alternatively choose to search, not the search contexts as
     defined by the context regexp you provide, but the non-contexts, that
     is, the text in the files that does not match the regexp.  To do this,
     use `CM- ~ 'during completion.  (This is a toggle, and it affects only
     future search commands, not the current one.)

See also this page for more information on Icicles :

http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview

+1
source share

All Articles