Running rgrep is not interactive

I try to run the rgrep command from a small Emacs Lisp utility, but I get a strange error. Team Description:

rgrep is an interactive compiled Lisp function.

(rgrep REGEXP & optional FILES DIR CONFIRM)

Recursively grep for REGEXP in FILES in the directory tree embedded in DIR. Search is limited to file names matching the FILES shell pattern. FILES can use abbreviations defined in grep-files-aliases', eg entering ch', equivalent to `*. [Ch] '.

With the Cu prefix, you can edit the built shell command line before it is executed. With two Cu prefixes, directly edit and run the `grep-find-command.

Collect the output in a buffer. Although the search is asynchronous, you can use Cx `(Mx next-error) or RET in the grep output buffer to jump to the lines where grep was encountered.

This command shares argument histories with Mx lgrep and Mx Grep find.

I am trying to run:

 (rgrep "something" "all" "~/projects/") 

and i get

  *** Eval error *** Wrong type argument: stringp, nil 

Obviously, all parameters are strings, so I cannot figure out where this nil comes from.

I am running Emacs 23.3 to test Debian.

Thanks in advance for your help!

+6
source share
4 answers

I think because you do not have "grep-find-template". this, of course, is (debugged) why the command creates an error in my version. look at the help for this variable.

greetings.

ps. this is the difference between an online call or not.

 "find . <X> -type f <F> -print0 | \"xargs\" -0 -e grep <C> -nH -e <R>" 

.. is set using "grep-calc-defaults" on an interactive call

SFC. I think you just need to be careful with your call. if no matches are found, you will receive the error message "Grep error with anonymous code 123".

 mkdir -p ~/a/b cp ~/.bash* ~/a/b emacs -q Cx b <RET> *scratch* (grep-compute-defaults) (rgrep "^.*\\?\=.*$" "*bash*" "~/a") 

.. many matches!

+4
source

The reason you get this when rgrep programmed programmatically is because all interactive calls to grep options have a grep-compute-defaults call in an interactive call. This is not evaluated in software programming.

The easiest way to fix this is to add

 (eval-after-load "grep" '(grep-compute-defaults)) 

in your code that will make it call (but only if necessary).

+3
source

It seems to me that it works fine:

 (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/") 
+2
source

According to the Emacs manual:

The Mx lgrep (local grep) and Mx rgrep (recursive grep) commands are more user-friendly versions of grep and grep-find, which query separately for the regular expression, search files, and the base directory to search.

For this problem, we do not need this "user-friendly" that interferes. We can use the regular grep elisp function, which is better suited for non-interactive use. Basically, this function takes as argument any grep command line that you should use to achieve the desired result. Maximum flexibility!

Here's what it would look like for your scenario:

 (grep "grep --color -rn something ~/projects/") 

Here's another, more complex use of grep options to match only complete words in Python files:

 (grep "grep --include=\"*.py\" --color -rnw your_pattern files_root_dir") 
+1
source

Source: https://habr.com/ru/post/894738/


All Articles