帮助编写emacs lisp用于emacs etags搜索

时间:2010-12-17 20:40:10

标签: emacs lisp elisp

我正在寻找一些帮助来开发我认为应该是一个简单的程序。

我想要类似于Emacs tags-search命令,但我想将所有搜索结果收集到缓冲区中。 (我希望看到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

我希望能够使用相同的功能浏览缓冲区 - apropos。

请注意,之前曾提出过类似的问题: Is there a way to get emacs tag-search command to output all results to a buffer?

3 个答案:

答案 0 :(得分:1)

以下是我用于为个人笔记创建标记系统的代码。它使用书签并将书签中的每个单词视为单个标记。它不是你想要的,但它可能会让你开始。

前几个函数可能已经在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))))

然后我将'tagging'行为绑定到一个键(F11),将'lookup'行为绑定到另一个键(F12)。

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

希望这对你有用。

答案 1 :(得分:1)

由于我是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)))

答案 2 :(得分:1)

这就是你想要的:

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