I’ve been using consult-ripgrep for this. It’s integrated with consult so you can view the context when moving between results in consult minibuffer
The way consult-ripgrep uses two-stage filtering is quite ingenious, especially when combined with a package like orderless. It’s also possible to pass ripgrep flags with this syntax:
#some rg query -- --some-flag --another-flag#some orderless filter
Basically everything is exposed while preserving a very concise syntax. It’s especially nice with the orderless dispatchers so for example !test excludes all the tests.
I am extremely happy with deadgrep, mainly because it’s so easy to iterate on improving the search results as needed, and despite the name, it uses ripgrep under the hood
Thanks, I’m using this now and it’s great
I’m using projectile-ripgrep (fits in neatly into Projectile).
The projectile-grep(s) are really good. Be sure to ignore entire directories with a .projectile file (like node_modules and similar) to speed things up. Also wgrep is a good package to edit grep results across many files, in one buffer, and then saving all changes at once.
I use the command rg with the Emacs package dumb-jump. This is probably not the most popular way of using rg with Emacs but I have been quite happy with the results. All I need to do is package-install the dumb-jump package and configure the following hook:
(add-hook 'xref-backend-functions #'dumb-jump-xref-activate)
Now the familiar Xref key sequences and commands work fine with it. For example, 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/
Note how it automatically restricts the search to Python files and the current project directory. If no project directory is found, it defaults to the home directory.
It 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 above comment: rg can be used quite easily with the project.el package too that comes out of the box. This is especially useful when we do not want a package like dumb-jump to perform smart things (ironical?) like restricting searches to a specific file type. We need to configure the following first 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:
C-x p g foo RET
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 Emacs with external search tools.
wow, I really liked your solution,
I did not know that how to configure project.el to default to ripgrep
it definitely makes my life easier,
I’ve never used dumb-jump before, but I bet it’s an interesting tool
thanks for sharing your experience
I’ve found if grep isn’t fast enough, then I probably just need to trim out more paths I don’t use.
This only really bites me when the source code is mounted over some shared storage system rather than local on my ssd. Then none of these matter - it’s the file reads at all that dominate. That’s where async indexing like cscope win out quickly, you can get all the reads out of the way.
I’m definitely interested in how other people do this. But why is this better than just invoking rg as a shell command in emacs?
Because the result buffer is navigable with keybindings
well you get a lot of goodies when you use ripgrep inside emacs (via rg.el), like quicly jumping to the files, or previewing the matched files, or on top of it all, if you use wgrep then you can apply some changes on the results.
but again, I agree that using ripgrep via rg causes you to lose some minor ripgrep’s functionalities
For the example given, I would prefer to find LSP references.
Maybe append your flags to any existing flags.