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

efl*_*n00 6 lisp emacs 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
Run Code Online (Sandbox Code Playgroud)

我希望能够浏览具有相同功能标签的缓冲区 - apropos.

请注意,之前已经提出过类似的问题: 有没有办法让emacs tag-search命令将所有结果输出到缓冲区?

Tre*_*son 1

因为我是 的粉丝igrep,所以我会用它作为构建块。从那里开始,有两个简单的例程,您就完成了。有了这个库和这两个函数,您所要做的就是:

M-x igrep-tags ^SomeRegexp.*Here RET
Run Code Online (Sandbox Code Playgroud)

这是代码:

(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))))
Run Code Online (Sandbox Code Playgroud)

而且,因为文件列表可能会变得非常长,并且您可能不关心该列表是什么,所以您可以添加这两段代码,这将使文件名在 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))))))
Run Code Online (Sandbox Code Playgroud)

为了避免命令行太长,您可以使用以下代码(它创建一个包含 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))
Run Code Online (Sandbox Code Playgroud)

而且,对于使用 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)))
Run Code Online (Sandbox Code Playgroud)