3

I am aware that you can customise the "find" command executed when using "find-grep" with "setq grep-find-command" and define which file-patterns to ignore in the search. I would like to take this further and be able to read the patterns to ignore from a file.

Each framework or tool might generate different files that I would like to be ignored in search. For example, SASS generates ".sass-cache" folder, the Symfony framework stores the "logs" and the "cache" in respectively named folders, while Haskell stack creates a ".stack-work" folder.

Instead of customising the "find-grep" command to exclude all patterns from different frameworks/tools, I would prefer a system where you can add a ".findignore" file in the root folder of the project and "find-grep" should be picking up the exclusions from there.

A couple of questions:

1) Is there such a solution already out there?

2) If not, advice on how to go about the following two requirements would help me get started:

  • How can I detect the .findignore file upwards up to the root folder of the project (just like .gitignore).
  • How to load each line and sequence it as an argument to "find-grep"

I haven't done advanced emacs customisations so any hints would be appreciated.

5

Preferred solution

I have settled with using "ag" (The Silver Searcher) for search and "helm-ag" or "ag.el" for Emacs integration. "ag" allows you to specify a ".agignore" file where you can add file/directory patterns that will be ignored for the search - exactly what I was looking for. For example:

# .agignore
folder
file.txt
*.js

It also takes ".gitignore" and ".hgignore" into account

  1. Install "ag" (https://github.com/ggreer/the_silver_searcher)
  2. Use "helm-ag" mode if you're using "helm" (https://github.com/syohex/emacs-helm-ag)
  3. Use "ag" mode if you're not using "helm" (https://github.com/Wilfred/ag.el)

Less favourable solution

Achieving the same with "rgrep" or "grep-find" is more difficult. You can set the "grep-find-ignore-directories" or "grep-find-ignore-files" (for rgrep) as directory-local variables in a dir-locals.el file, like so:

# Reference: http://stackoverflow.com/a/16247272/1505303
((nil . ((eval . (progn
                   (require 'grep)
                   (add-to-list 
                    (make-local-variable 'grep-find-ignored-directories)
                    "folder-to-ignore"))))))

or (thanks to @phils answer for the direction):

((nil . ((grep-find-ignored-directories . ("folder-to-ignore"))
         (grep-find-ignored-files . ("file-to-ignore")))))

Both of these solutions though have the drawback that the directory-local variables are set from the folder defined and below. This means that if I make a search from the root folder of the project, or any parent folder, the undesired files will be included in the search.

Additionally, they are a bit more cumbersome and difficult to set up, especially for emacs beginners that do not understand elisp well enough.

It may be possible to write a function that looks for ".findignore" or ".grepignore" files in in the folder the search is being executed and below, convert the patterns from each file as relative to the folder, and then pass them as arguments to "find" or "grep". That would certainly be much slower than "ag" though, so it may not be worth developing.

1

For the lgrep command, you could set grep-find-ignored-files as a Directory Local variable.

For rgrep you could additionally (or alternatively) set grep-find-ignored-directories.

These tend to be much simpler than using find-grep (which calls grep-compute-defaults to determine the command, which is rather more complex to work with).

  • Hey, thanks for the response - it set me towards the right direction. It may be a bit more complicated - I've found the following stackoverflow.com/a/16247272. Also, setting this variable works for "rgrep" but not for "find-grep/grep-find" for me. I'll work a bit on it and if I manage to make it work I'll post back here. – krystalcode Dec 23 '15 at 0:25
  • That other Q&A is more complicated, but if you want to you can simply hard-code the complete list for the directory-tree in question in a normal (non-eval) dir-local value. – phils Dec 23 '15 at 0:44
  • Apologies, I was forgetting that those vars weren't for all the grep-find commands. grep-find calls grep-compute-defaults to determine the full command, and it's a bit complex. rgrep really simplifies things, if it's sufficient for your requirements. – phils Dec 23 '15 at 0:53
  • No worries. Setting "grep-find-ignored-directories" either directly, or using eval like stackoverflow.com/a/16247272 describes, get close, but have a major disadvantage. The local variable will not be set if you search from a parent folder and the undesirable paths will be included in the results. And if it is set globally, it will apply everywhere instead. I'll post an alternative as a separate answer. I'm upvoting you anyway as it helped me to get to the right direction. – krystalcode Dec 23 '15 at 17:15
  • Ah, righto. I had assumed you wanted to set this at the project root, such that you were never likely to perform a search from any parent/ancestor. I can't think of any easy way to do what you're talking about just using Emacs' own find/grep functionality -- I suspect it would be a case of constructing an extremely verbose find command. Some of the examples do sound like cases for adding to the global lists, mind you (.sass-cache, .stack-work). – phils Dec 23 '15 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.