如何在Emacs中使用M-x rgrep命令与git grep命令配合使用?

9
我想要能够使用正常的 M-x rgrep 工作流程(输入路径、模式并在 *grep* 缓冲区中显示链接的结果),但是使用 git grep 替代普通的 find 命令:
find . -type f -exec grep -nH -e  {} +

我尝试直接设置grep-find-command变量:

(setq grep-find-command "git grep")

并且使用 grep-apply-setting

(grep-apply-setting 'grep-find-command "git grep")

但似乎两者都不起作用。当我运行M-x rgrep时,它仍然使用之前的find命令。

事实上,我现在很确定rgrep甚至没有使用grep-find-command变量,但我无法弄清楚它的命令存储在哪里。

3个回答

13

那么 M-x vc-git-grep (C-x v f) 呢?它不能满足你的需求吗?

它会提示你输入:

  • 搜索模式(默认:光标所在位置或选中文本)
  • 文件名模式(默认:当前文件后缀)
  • 基础搜索目录(默认:当前目录)

对我而言效果不错。


哦,是的,我实际上不知道那个命令。对我来说,它也有与分页相同的问题,而不是直接返回结果。这可以通过相同的建议来解决。 - Tikhon Jelvis
而且它也不会使用默认的grep-files-aliases模式进行递归。需要为此添加建议。 - eush77

12

原来相关的变量实际上是 grep-find-template。 它需要一个带有几个附加参数的命令:

  • <D> 代表基本目录
  • <X> 代表查找选项以限制目录列表
  • <F> 代表查找选项以限制匹配的文件
  • <C> 代表放置 -i 的位置,如果搜索不区分大小写
  • <R> 代表要搜索的正则表达式

默认模板如下所示:

find . <X> -type f <F> -exec grep <C> -nH -e <R> {} +
为使命令与git grep合作,我需要传入一些选项以确保git不使用分页器并以正确的格式输出内容。我还忽略了一些模板选项,因为git grep已经以自然的方式限制了搜索的文件。但是,重新添加它们可能有意义。

grep-find-template的新值为:

git --no-pager grep --no-color --line-number <C> <R>

经过初步测试,看起来它似乎可以工作。

请注意,您应该使用grep-apply-setting设置此变量,而不是直接修改它:

(grep-apply-setting 'grep-find-template "git --no-pager grep --no-color --line-number <C> <R>")

因为我不使用rgrep的两个输入,所以我编写了自己的git-grep命令,它会暂时存储旧的grep-find-template并将其替换为我的命令。虽然这有点hacky,但似乎也能工作。

(defcustom git-grep-command "git --no-pager grep --no-color --line-number <C> <R>"
  "The command to run with M-x git-grep.")
(defun git-grep (regexp)
  "Search for the given regexp using `git grep' in the current directory."
  (interactive "sRegexp: ")
  (unless (boundp 'grep-find-template) (grep-compute-defaults))
  (let ((old-command grep-find-template))
    (grep-apply-setting 'grep-find-template git-grep-command)
    (rgrep regexp "*" "")
    (grep-apply-setting 'grep-find-template old-command)))

0

使用Windows版的Emacs和Git Bash时,请确保PATH能够找到git.exe,否则vc-git-grep将无法工作:

  (let ((dir "C:/Program Files/Tools/Git/bin"))
    (setenv "PATH" (concat (getenv "PATH") ";" dir))
    (setq exec-path (append exec-path '(dir))))

exec-path 不够用......原因在这里解释: 如何在Emacs中使用git

由于vc-git-grep使用运行函数的缓冲区目录,我还发现一个包装器很方便:

(global-set-key [(control f8)]
            (lambda() (interactive)
              (with-current-buffer ROOT (call-interactively #'vc-git-grep))))

这里的 ROOT 是一个缓冲区(或者是一个计算缓冲区的函数),从该目录开始进行搜索。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接