39

What is the easiest way to search for a regexp throughout the contents all files in the current project, skipping files that are not useful?

Useless files are things like compiled files, imported libraries, version-control files, etc.

I’m aware of rgrep, but it just searches everything. Is there a package that searches ‘inteligently’ and knows about several different programming languages, so I wouldn’t have to configure it for each individual project?

Malabarba
  • 22,878
  • 6
  • 78
  • 163
  • 1
    Your "it just searches everything" comment about `rgrep` is a little confusing, given that it excludes all files matching your "useless files" criteria by default. – phils Sep 20 '15 at 22:22

5 Answers5

40

Project based searching within Emacs can be done using projectile.

It allows for per-project configuration of ignore files (in a <projectroot>\.projectile file), or specify subdirectories to monitor and ignore all others.

It can run grep, ack (requires ack-and-a-half.el) and ag (ag.el) on files within the defined project (either based on the .projectile file or by finding a supported VC file to define a project root).

Useful Commands

(With regards to searching through useful files)

As per Projectile Readme

  • C-c p s g :: Run grep on the files in the project.
  • C-c p s a :: Runs ack on the project. Requires the presence of ack-and-a-half.
  • C-c p s s :: Runs ag on the project. Requires the presence of ag.el.
  • C-c p f :: Display a list of all files in the project.
  • C-c p d :: Display a list of all directories in the project.
  • C-c p a :: Switch between files with the same name but different extension in the project.
  • C-c p o :: Runs multi-occur on all project buffers currently open.

These will only act on files defined as being part of the project (or found when the cache is generated/regenerated).

Jonathan Leech-Pepin
  • 4,307
  • 1
  • 19
  • 32
14

The project-wide search of only relevant files can be done using ag aka the_silver_searcher.

Why ag?

  • It ignores file patterns from your .gitignore, .hgignore, svn:ignore. You can choose for your searches to NOT use the ignore list from the version-control ignore lists by using the -U switch.
  • If there are files in your source repo you don't want to search, just add their patterns to a .agignore file.
    • A global .agignore file can be put in your $HOME and then you can put more project specific .agignore files in your project roots.

Setting up ag and emacs

  • Install ag aka the_silver_searcher on your system.
  • Set up the .agignore file. I prefer to have just a global .agignore file in my $HOME.
  • Install the ag package (available on Melpa).
  • You can then use the ag-project or ag-project-regexp function (that come with the ag package) to do project-wide file searches.
    • By default, these functions use the root of the VCS repo as the directory to search in. You can override this by setting or customizing the ag-project-root-function.
    • Even if your project is not git controlled, you can mark a project-root for the ag-project / ag-project-regexp based searches by putting an empty .git folder in your project root. You then don't have to customize ag-project-root-function.
Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179
7

If your project uses Git, you only need counsel https://github.com/abo-abo/swiper

  • counsel-git to find file

  • counsel-git-grep to grep

The only dependency is git

Text grepping is faster than the silver searcher (ag)

Counsel also provides other powerful tools. For example, after running counsel-git-grep, you can press C-c C-o and C-x C-q to go into wgrep-mode to easily replace text in the project scope.

There is an article https://sam217pa.github.io/2016/09/11/nuclear-power-editing-via-ivy-and-ag/ explaining details. That article uses counsel-ag (another command built into counsel) but cousnel-git-grep uses exactly same work flow.

chen bin
  • 4,781
  • 18
  • 36
  • But how come text-grepping is faster than ag? Could you please elaborate? – denis631 Oct 24 '19 at 22:03
  • 1
    `ag` is also a grep program, like `git-grep`. I can't say which is faster. See https://github.com/BurntSushi/ripgrep which compares the performance of popular grep programs (including `ag` and `git-grep`) – chen bin Oct 25 '19 at 00:36
  • When I am using `counsel-git-grep`; can it recognize for example char `[` right away instead of typing it as `\[` – alper Nov 15 '20 at 23:51
  • This is way better than projectile's grep, IMO – Aaron Apr 29 '21 at 07:47
1

The first answer is beautiful, but it leaves out some critical details about modern versions of Emacs. I am knew to Emacs myself, so other newcomers might not be aware of this. Given your goal is to search for text WITHIN a file in a PROJECT, then you would first install Projectile using the MELPA repository.

This installs the package in .emacs.d and adds some basic configuration to .emacs in your $USER directory (assuming you had created the .emacs file), such as requiring Projectile in your Emacs install.

However, you still need to enable it and associate keymap prefixes, so you can invoke it in the mini buffer.

The accepted answer mentions the following command:

C-c p s g

This will not work, unless you configure Projectile with this keymap prefix. But I configured it to use C-c C-p as the command for Project in .emacs:

(projectile-mode +1)
(define-key projectile-mode-map (kbd "C-c C-p") 'projectile-command-map)

Now given this, I am able to perform text searches in files in a project using grep:

C-c C-p f # switch to a project first
C-c C-p s g # perform grep search in project

To break it down, C-c C-p will invoke Projectile, and s g will perform the grep search. You will get a beautiful output like this, assuming your search is visit_contact and you are searching Ruby's rspec in a project:

./spec/support/capybara_classification_code_helper.rb:21:  def visit_contact
./spec/features/admin_edits_classification_code_role_dynamic_field_spec.rb:8:    visit_contact
./spec/features/admin_edits_classification_code_role_dynamic_field_spec.rb:33:    visit_contact
./spec/features/user_views_global_filters_from_line_item_spec.rb:9:      visit_contact
Daniel Viglione
  • 186
  • 1
  • 5
1

M-x rgrep search-pattern *.[c,h]

young_souvlaki
  • 526
  • 2
  • 13