我正在尝试从一个小的Emacs Lisp实用程序运行rgrep命令,但是我得到了一个奇怪的错误。命令描述是:
rgrep是一个交互式编译的Lisp函数。
(rgrep REGEXP& optional FILES DIR CONFIRM)
以源自DIR的目录树中的FILES中的REGEXP递归grep。 搜索仅限于与shell模式FILES匹配的文件名。 FILES可以使用
grep-files-aliases', e.g. entering
ch'中定义的缩写等同于`*。[ch]'。使用C-u前缀,您可以编辑构造的shell命令行 在执行之前。有两个C-u前缀,直接编辑和运行 `grep的找到的命令”。
在缓冲区中收集输出。虽然find可以异步运行,但您可以 使用C-x`(M-x next-error)或grep输出缓冲区中的RET来转到 发现grep匹配的行。
此命令与M-x lgrep和M-x共享参数历史记录 的grep-发现。
我试着跑:
(rgrep "something" "all" "~/projects/")
我得到了
*** Eval error *** Wrong type argument: stringp, nil
显然所有的参数都是字符串,所以我无法理解这个零来自哪里。
我在Debian测试中运行Emacs 23.3。
提前感谢您的帮助!
答案 0 :(得分:4)
我认为这是因为你没有定义'grep-find-template'。这肯定是(已经调试过)为什么命令会在我的版本上产生错误。看看那个变量的帮助。
欢呼声。
PS。它是以交互方式调用它之间的区别..
"find . <X> -type f <F> -print0 | \"xargs\" -0 -e grep <C> -nH -e <R>"
交互式调用..由'grep-calc-defaults'设置
PPS。我想你只需要小心你的电话。如果没有找到匹配项,您将收到“Grep异常退出代码123”错误。
mkdir -p ~/a/b
cp ~/.bash* ~/a/b
emacs -q
C-x b <RET> *scratch*
(grep-compute-defaults)
(rgrep "^.*\\?\=.*$" "*bash*" "~/a")
..很多比赛!
答案 1 :(得分:3)
当您以编程方式致电rgrep
时,您收到此消息的原因是interactive
对grep
变种的grep-compute-defaults
次调用interactive
调用了(eval-after-load "grep"
'(grep-compute-defaults))
{{1}}调用。当您以编程方式调用时,不会对此进行评估。
解决此问题的最简单方法是添加
{{1}}在您的代码中
,这将强制调用它(但仅在需要时)。
答案 2 :(得分:2)
以下似乎对我有用:
(defadvice rgrep (around rgrep-init)
"Init grep defaults before calling rgrep non-interactively."
(when (not (called-interactively-p))
(grep-compute-defaults))
ad-do-it)
(ad-activate 'rgrep)
(rgrep "something" "all" "~/projects/")
答案 3 :(得分:1)
根据Emacs手册:
命令Mx lgrep(本地grep)和Mx rgrep(递归grep)是更加用户友好的grep和grep-find版本,它们分别提示正则表达式匹配,要搜索的文件和基本目录搜索。
对于手头的问题,我们不需要这种妨碍这种“用户友好性”的问题。我们可以使用简单的“grep”elisp函数,它更适合非交互式使用。基本上,无论您使用什么grep命令行来实现所需的结果,此函数都将参数作为参数。最大的灵活性!
以下是您的方案的样子:
(grep "grep --color -rn something ~/projects/")
这是grep选项的另一个更复杂的用法,只匹配Python文件中的完整单词:
(grep "grep --include=\"*.py\" --color -rnw your_pattern files_root_dir")