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?

  • 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

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).

  • Thanks, what's the projectile command that I can use for this?
    – Malabarba
    Sep 29 '14 at 13:16
  • Edited it to include a subset of the commands (those dealing with search, find-file and dired). Full list is in the package readme. Sep 29 '14 at 13:50

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.

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.

  • 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 github.com/BurntSushi/ripgrep which compares the performance of popular grep programs (including ag and git-grep)
    – chen bin
    Oct 25 '19 at 0: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 at 7:47

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

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

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.