2010-12-17 10 views
6

Poszukuję pomocy w opracowaniu tego, co moim zdaniem powinno być prostym programem.Pomoc w pisaniu wiadomości e-mail dla emacs etags szukaj

Chcę coś podobnego do polecenia wyszukiwania tagów Emacsa, ale chcę zebrać wszystkie wyniki wyszukiwania do bufora. (Chcę zobaczyć wszystkie wyniki M-,)

Myślę, że ten pseudo-kod w stylu Pythona powinien zadziałać, ale nie mam pojęcia, jak to zrobić w emacs seplenieniu? Każda pomoc będzie bardzo ceniona.

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 

Chciałbym móc przeglądać bufor z tymi samymi znacznikami funkcji - robi to apropos.

Należy zauważyć, że podobne pytanie zostało zadane wcześniej: Is there a way to get emacs tag-search command to output all results to a buffer?

+1

Podobnie jak z boku, spojrzeć na pętli makro Lisp (kilka przykładów tutaj http: // www. ai.sri.com/pkarp/loop.html) Myślę, że ci się spodoba. – ocodo

Odpowiedz

1

Ponieważ jestem takim fanem igrep, użyłbym tego jako elementu konstrukcyjnego. Stamtąd to dwie proste procedury i gotowe.Z tej biblioteki i tych dwóch funkcji, wszystko co musisz zrobić, to:

M-x igrep-tags ^SomeRegexp.*Here RET 

Oto kod:

(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)))) 

A ponieważ lista plików może się naprawdę długo, a prawdopodobnie don” obchodzi co ta lista jest, można dodać te dwa kawałki kodu, który spowoduje, że nazwy plików niewidoczne po grep zakończył:

(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)))))) 

Aby uniknąć wiersza poleceń naprawdę długa, można użyć następującego kodu (co tworzy tymczasowy plik zawierający wszystkie nazwy plików z pliku tagi i korzysta że zamiast):

(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)) 

A dla tych, za pomocą Emacs 22 lub wcześniej, musisz rutynę, która jest dostarczona z Emacs 23 (od 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))) 
+0

Podoba mi się to rozwiązanie, ale w przypadku niektórych z moich TAGów liczba plików jest zbyt długa, aby można było z nimi poradzić. Jakikolwiek sposób to zrobić, powtarzając każdy plik w TAGach? – eflanigan00

+0

@ user535707 Dodałem rozwiązanie, które rozwiązuje twój problem. –

+0

Dziękuję za sugestię, ale nie mogę używać ciągów łączonych i cudzysłowów na emacs22. Czy istnieje inna funkcja, którą mogę napisać, aby ją zastąpić. – eflanigan00

1

Oto kod używam do stworzenia systemu tagów dla moich osobistych notatek. Używa zakładek i traktuje każde słowo w zakładce jako pojedynczy tag. Nie jest to dokładnie to, czego szukasz, ale może zacząć.

Pierwsze kilka funkcji jest prawdopodobnie już zaimplementowanych w emacs, ale napisałem własne z powodów, których już nie pamiętam.

;; 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)))) 

Następnie wiążę zachowanie "znakowania" z kluczem (F11) i zachowanie "wyszukiwania" dla innego (F12).

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

Nadzieję, że jest przydatna.

+0

Dobry Victor Eye, myślę, że opublikowałem tylko raz lub dwa razy. Na pewno to sprawdzę. –

1

to jest to, co chcesz:

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

jest to ciąg doc dla 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 `C-M-~' during completion. (This is a toggle, and it affects only 
    future search commands, not the current one.) 

Zobacz także aktualizacja dalszych wyjaśnień o Sople wyszukiwania:

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

+0

Działa to wystarczająco dobrze, ale naprawdę nie ma wystarczającej ilości informacji, aby dobrze wybrać. Rozwiązanie firmy igrep opublikowane przez Trey zapewnia cały kod źródłowy na linii zwróconej przez grep. Bardzo chciałbym, żeby sople scalały coś takiego, a nawet dodawały opcję -A i -B do grep. – eflanigan00

+1

@flanigan: Nie jestem pewien co masz na myśli. To, co robi 'icicle-tags-search', to: Odwiedź swoje pliki TAGS, aby uzyskać listę wszystkich plików, które mają zdefiniowane znaczniki, a następnie przeszukaj wszystkie te pliki. Wyszukiwanie polega na wyszukiwaniu sopli, co oznacza, że ​​podajesz wyrażenie regularne, które definiuje konteksty wyszukiwania. Jeśli chcesz, aby każda linia była kontekstem jak w 'grep', użyj'. * 'Jako wyrażeń regularnych definiujących kontekst. Następnie wpisujesz tekst (na przykład podłańcuch lub wyrażenie regularne) w minibuforze, aby filtrować zestaw kontekstów (ze wszystkich plików). Możesz użyć 'S-SPC', aby dodać więcej wzorów filtrowania, aby stopniowo zawęzić konteksty. – Drew

+1

Jeśli nie jesteś zaznajomiony z wyszukiwaniem sople, proponuję najpierw spróbować proste wyszukiwanie: pojedynczy plik, na przykład. Rozpocznij [* tutaj *] (http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview). Domyślam się, że nie masz pewności co do regexp kontekstu, myśląc, że jest on używany do przeszukiwania plików. Aby wyszukać wiersz po wierszu a la 'grep', wyrażenie regexp powinno być po prostu'. * '. Wyszukiwanie odbywa się za pomocą dynamicznych wzorców wyszukiwania, które wpisujesz w minibuforze. – Drew