back
188 comments
It's fast indeed. And I can't help keeping promoting the combination with fzf :) For those who want to try it out, this is a Powershell function but the same principle applies in any shell. Does ripgrep then puts fuzzy searching in the resulting files+text on top while showing context in bat:

  function frg {
    $result = rg --ignore-case --color=always --line-number --no-heading @Args |
      fzf --ansi `
          --color 'hl:-1:underline,hl+:-1:underline:reverse' `
          --delimiter ':' `
          --preview "bat --color=always {1} --theme='Solarized (light)' --highlight-line {2}" `
          --preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
    if ($result) {
      & ($env:EDITOR).Trim("`"'") $result.Split(': ')[0]
    }
  }
There are other ways to approach this, but for me this is a very fast way of nailing down 'I now something exists in this multi-repo project but don't know where exactly nor the exact name'

edit this comes out of https://github.com/junegunn/fzf/blob/master/ADVANCED.md and even though you might not want to use most of what is in there, it's still worth glancing over it to get ideas of what you could do with it

Infact I would recommend a step further to integrate rip-grep-all (rga) with fzf that can do a fuzzy search not just on text files but on all types of files including pdfs, zip files. More details here [1]

[1] https://github.com/phiresky/ripgrep-all/wiki/fzf-Integration

I wrote a bash version of this:

  function frg {
    result=`rg --ignore-case --color=always --line-number --no-heading "$@" |
      fzf --ansi \
          --color 'hl:-1:underline,hl+:-1:underline:reverse' \
          --delimiter ':' \
          --preview "bat --color=always {1} --theme='Solarized (light)' --highlight-line {2}" \
          --preview-window 'up,60%,border-bottom,+{2}+3/3,~3'`
    file="${result%%:*}"
    linenumber=`echo "${result}" | cut -d: -f2`
    if [ ! -z "$file" ]; then
            $EDITOR +"${linenumber}" "$file"
    fi
  }
Vim is almost broken for me without fzf+rg. Feels like I’m manually grinding coffee instead of using electricity.
With fzf you can add lots of files to git while skipping some if you want:

    fza = "!git ls-files -m -o --exclude-standard | fzf -m --print0 | xargs -0 git add"
With that in the [alias] section of a gitconfig file, running git fza brings up a list of modified and not yet added files, space toggles each entry and moves to the next entry.

That alias as well as fzf+fd really speed up some parts of my workflow.

Oh and shameless plug for my guide on what to include in your zsh setup on macOS: https://gist.github.com/aclarknexient/0ffcb98aa262c585c49d4b...

This is pretty much my exact use of ripgrep, too. I use it as a starting point to zero in on files/projects in a several-hundred repo codebase, and then go from there....
Not bad. For those who want to try it, install all prereqs with: choco install fzf bat ripgrep

How do you scroll the preview window with keyboard ?

Oh. Thanks for the tip. This might make me finally embrace powershell. I’ve been using WSL+zsh+fzf as a Windows CLI for continuity with day job Mac tools, but git CLI performance is only usable inside the WSL file system.
Thanks for this!
I use it neovim with fzf search.
This is a gem; thank you.
I use ripgrep with the Emacs packages project.el (comes out of the box) and dumb-jump (needs to be installed). This may not be the most popular way of using rg but I have been very pleased with the overall experience. All it takes is running package-install to install the dumb-jump package and configuring the following hook:

  (add-hook 'xref-backend-functions #'dumb-jump-xref-activate)
The Xref key sequences and commands work fine with it. If I type M-. (or C-u M-.) to find definitions of an identifier in a Python project, dumb-jump runs a command like the following, processes the results, and displays the results in an Xref buffer.

  rg --color never --no-heading --line-number -U --pcre2 --type py '\s*\bfoo\s*=[^=\n]+|def\s*foo\b\s*\(|class\s*foo\b\s*\(?' /path/to/git/project/
The above command shows how dumb-jump automatically restricts the search to the current file type within the current project directory. If no project directory is found, it defaults to the home directory.

By the way, dumb-jump supports the silver searcher tool ag too which happens to be quite fast as well. If neither ag nor rg is found, it defaults to grep which as one would expect can be quite slow while searching the whole home directory.

Addendum to my comment above:

Ripgrep can be used quite easily with the project.el package too that comes out of the box in Emacs. So it is not really necessary to install an external package to make use of ripgrep within Emacs. We first need to configure xref-search-program to ripgrep as shown below, otherwise it defaults to grep which can be quite slow on large directories:

  (setq xref-search-program 'ripgrep)
Then a project search with C-x p g foo RET ends up executing a command like the following on the current project directory:

  rg -i --null -nH --no-heading --no-messages -g '!*/' -e foo
The results are displayed in an Xref buffer again which in my opinion is the best thing about using external search tools within Emacs. The Xref key sequences like n (next match), p (previous match), RET (jump to source of match), C-o (show the source of the match in a split window), etc. make navigating the results a breeze!
Author of ripgrep here.

Looking at your regex---just by inspection, I haven't tried it, so I could be wrong---but I think you can drop the --pcre2 flag. I also think you can drop the second and third \b assertion. You might need the first one though.

Deadgrep (uses ripgrep and evil-collection has a binding) takes me to my happy place -

https://github.com/Wilfred/deadgrep

this is a good option but i still use rg.el for the occasion that i want to search several projects at once or a subfolder within a project, where i would otherwise use ‘rgrep’
What's interesting is that ripgrep now also powers VS Code search with a Node.js wrapper.

https://www.npmjs.com/package/@vscode/ripgrep

...which is awesome if you can request/install VS Code but not ripgrep.

You can find the rg binary in the VS installation (at least, I can on Windows at my place of employment).

I've always wondered how in world search in VS Code is so fast given it's an Electron app - now I know.
It's not new it has been in vscode for 7 years.
I did not know this that's actually very interesting.
I've been using ripgrep for about 2 years now and I find in indispensable. The main reason I switched from grep was ease of use. From the README: "By default, ripgrep will respect gitignore rules and automatically skip hidden files/directories and binary files." Typing `rg search_term directory` is much better than the corresponding grep command, but the speed improvement is also a nice bonus.

Random other helpful flag I use often is -M if any of the matches are way too long to read through and cause a lot of terminal chaos. Just add `-M 1000` or adjust the number for your needs and the really long matches will omit the text context in the results.

Yeah, the -M command is wonderful (super handy for ignoring minified files that you don't want to see results from, etc), and also great is the -g command (eg `-g *.cs` and you'll just search in files that have the .cs extension).

Also the fact that it is a standalone portable executable can be super handy. Often when working on a new machine, I'll drop in the executable and an alias for grep that points to rg, so if muscle memory kicks in and I type grep it will still use rg.

And this may still be true in 2023, but the problem is that most of the parallelized grep replacements (e.g. ripgrep, ag, etc.) are SO much faster than grep that the much small speed differences between them doesn't provide much of a basis for differentiating them.

I use ag (typically from inside Emacs) on a 900k LOC codebase and it is effectively instantaneous (on a 16 core Ryzen Threadripper 2950X). I just don't have a need to go from less than 1 second to "a bit less than less than 1 second".

Speed is not the defining attribute of the "new greps" - they need to be assessed and compared in other ways.

In 2016, I'd say speed was definitely a defining attribute. ag has very significant performance cliffs. You can see them in the blog post.

But as I mentioned in my comparison to qgrep elsewhere in the thread, everyone has different workloads. And for some workloads, perf differences might not matter. It really just depends. 900 KLOC isn't that big, and indeed, for simple queries pretty much any non-naive grep is going to chew through it very very quickly.

As for comparisons in other ways, at least for ag, it's on life support. I thought it was going to get removed from Debian, but it looks like someone rescued it: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=999962

The blog post also compares Unicode support, and contextualizes its performance. ag essentially has zero Unicode support. Unicode support isn't universally applicable of course---you may not care about it---but it satisfies your non-perf comparison criteria. :-)

The title needs “(2016)”. This is the original announcement, not new information.
well... it is not faster than qgrep :) even though the way both work - differs greatly, and even though qgrep is based on re2 - the speed comes from the presence of index. but then I wonder why people forget the qgrep option, since with large file stores it makes much more sense to use qgrep AND indices, rather than always go through all the files.

this above all true UNLESS you need multi-line matches with UTF8, where ripgrep is not so fast, because it needs to fall back to the other PCRE2 lib

I switched from from ripgrep to ugrep and never looked back. It's just as fast, but also comes with fuzzy matching (which is super useful), a TUI (useful for code reviews), and can also search in PDFs, archives, etc.

The optional Google search syntax also very convenient.

https://ugrep.com

What are the reasons for grep not being replaced/improved? This topic seems a bit old by now.
I searched in portage, and it seems there is another version working also with other documents like PDFs and doc.

https://github.com/phiresky/ripgrep-all

Using Ripgrep via Consult [1] in Emacs is bliss. It's like the rg+fzf thing that some have made, but all inside Emacs. I use the `consult-ripgrep` command all the time, and sometimes I use it to make project-wide edits too! Workflow is search with `consult-ripgrep` -> export results to buffer -> edit buffer -> commit edits back to files. Details at [2] (includes video of me working it)

[1]: https://github.com/minad/consult#grep-and-find [2]: https://lambdaland.org/posts/2023-05-31_warp_factor_refactor...

Grep is already pretty much instant so what does it matter?
One thing I wish ripgrep had is support for AND conditions.
ripgrep is easily one of my most used and most loved tools. I use it directly and also have it set as my grpprg in neovim.
I messed up my conda environments once when I changed my username. So many references to the old username in the conda folders. Ripgrep saved the day!
I've been using ripgrep for the last year to quickly search massive database dumps. I compared it with grep and it's a game changer.
Semi off-topic, I've coded a ncurses-frontend to navigate and filter grep-like results which might be of interest to some of you: https://github.com/gquere/ngp2
But is any of them using `_mm256_sad_epu8` for small, literal strings?
Would be nice if ripgrep was drop in compatible with grep. I'd feel like a dick writing a shell script for other people to use and forcing them to install a new grep
I love ripgrep for the speed and the more sane defaults. I use it nearly every day.

For those just using it to search through a codebase, don't forget -F for string literals.

I love ripgrep, it's searched a directory in a half-second for a pattern that took GNU grep literally fifteen minutes.
Feels like it should always be included by default on grep level now.
I've been using ag forever - will check out ripgrep.
I can't think of a single time I've used grep where I thought "I wish this was faster".
git grep cannot even find a simple string in its repo.