Помогите написать emacs lisp для поиска в emacs etags - PullRequest
6 голосов
/ 17 декабря 2010

Мне нужна помощь в разработке простой программы.

Мне нужно что-то похожее на команду поиска тегов Emacs, но я хочу собрать все результаты поиска в буфер.(Я хочу увидеть все результаты M -,)

Я думаю, что этот псевдокод в стиле Python должен работать, но я не знаю, как это сделать в emacs lisp?Любая помощь будет принята с благодарностью.

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

Я хотел бы иметь возможность просматривать буфер с теми же функциями, что и tags-apropos.

Обратите внимание, что подобный вопрос задавался ранее: Есть ли способ получить команду поиска тегов emacs для вывода всех результатов в буфер?

Ответы [ 3 ]

1 голос
/ 18 декабря 2010

Так как я такой фанат igrep, я бы использовал его как строительный блок.Оттуда это две простые процедуры, и все готово.С этой библиотекой и этими двумя функциями все, что вам нужно сделать, это:

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

Вот код:

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

И, поскольку список файлов может быть очень длинным, ивам, вероятно, все равно, что это за список, вы можете добавить эти два фрагмента кода, которые сделают имена файлов невидимыми после завершения grep:

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

Чтобы избежать очень длинной командной строки, вы можетеиспользуйте следующий код (который создает временный файл, содержащий все имена файлов из файла TAGS и использует его вместо этого):

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

И для тех, кто использует Emacs 22 или более раннюю версию, вам понадобится процедурапоставляется с Emacs 23 (из 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 голос
/ 20 августа 2011

Это то, что вы хотите:

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

Это строка документа для 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.)

См. Также эту страницу для получения дополнительной информации о Сосульки Поиск:

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

1 голос
/ 18 декабря 2010

Вот код, который я использую для создания системы тегов для моих личных заметок.Он использует закладки и рассматривает каждое слово в закладке как один тег.Это не совсем то, что вы ищете, но это может помочь вам начать.

Первая пара функций, вероятно, уже реализована в emacs, но я написал свою собственную по причинам, которые я больше не помню.

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

Затем я связываю поведение тегирования склавиша (F11) и поведение «поиск» к другому (F12).

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

Надеюсь, что это полезно для вас.

...