resharp-grep 0.3.5

a grep-like search tool powered by the resharp regex engine
resharp-grep-0.3.5 is not a library.

re

grep finds one thing at a time. re finds where multiple things appear together - on the same line, in the same paragraph, within N lines of each other, or anywhere in the same file. powered by RE#.

install | web playground

why re

# find unsafe code that unwraps within 5 lines - potential panics in unsafe blocks
re --near 5 --and unsafe --and unwrap src/

# find errors mentioning timeout, but filter out debug and trace noise
re error --not debug --not trace src/

# list files that use both tokio and diesel - mixed async/sync code
re --scope file --and tokio --and diesel src/

# find paragraphs that mention both password and plaintext - credential exposure
re -p password -p plaintext .

# search within YAML sections for entries that have both host and port
re --scope '---' --and host --and port config/

# find markdown sections that discuss both API and deprecation
re --scope '\n## ' --and API --and deprecated docs/

with grep, each of these would require chaining multiple commands and losing file context, line numbers, and highlighting. re does it in one shot, and faster than any other tool out there.

quick start

re works similar to ripgrep for simple searches:

re TODO src/                              # find TODO in src/
re -i error .                             # case-insensitive search
re -F 'std::io' src/                      # literal string (no regex)

the difference shows up when you need more than one term.

boolean constraints

-a requires a term, -N excludes one. all terms must co-occur within the current scope (line by default).

# lines containing both "error" and "timeout"
re -a error -a timeout src/

# error but not debug - filter out noisy log lines
re error -N debug .

# lines with both literal strings (no regex interpretation)
re -F 'std::io' -F 'Error' src/
flag effect compiles to
-a / --and match must also contain this pattern &(_*pattern_*)
-N / --not match must not contain this pattern &~(_*pattern_*)
-F / --lit match must contain this literal string &(_*literal_*)

scope

by default, all terms must appear on the same line. -d (delimiter/scope) widens the window.

scope flag terms must appear within
line (default) a single line
paragraph -p a text block separated by blank lines
file -d file anywhere in the same file (lists filenames)
proximity --near N N lines of each other
custom -d '<delim>' text between occurrences of the delimiter
# find text blocks that mention both "error" and "retry"
re -p error -p retry logs/

# list files that import both serde and async-trait
re -d file -a serde -a async-trait src/

# find markdown sections discussing both API and deprecation
re -d '\n## ' -a API -a deprecated docs/

# find TODO and FIXME within 3 lines of each other - related work items
re --near 3 -a TODO -a FIXME .

-p word is shorthand for --scope paragraph -a word.

the RE# pattern language

the flags are convenient shorthands, but you can also write the whole pattern as a single positional argument using boolean operators directly:

operator meaning example
& intersection - both sides must match (error)&(timeout) matches lines with both
~(...) complement - must not match ~(_*debug_*) excludes lines containing debug
_ wildcard - any character including newlines _*error_* matches error anywhere in a block
# these are equivalent:
re error -N debug .
re '(_*error_*)&~(_*debug_*)' .

# patterns that go beyond what flags can express:
# hex strings that contain both a digit and a letter
re '([0-9a-f]+)&(_*[0-9]_*)&(_*[a-f]_*)'

use \_ for a literal underscore, -R for standard regex mode, or -F for fixed strings.

try patterns interactively in the web playground.

differences from ripgrep

most ripgrep flags work the same. the key differences:

ripgrep re notes
-a processes binary files -a means --and (require term) use -uuu for binary file processing
_ is a literal character _ is a wildcard use -R or \_ for literal underscore
standard regex only adds &, ~, _ operators use -R to disable

exit codes

0 match found, 1 no match, 2 error

install

cargo

cargo install resharp-grep  # installs binary named `re`

prebuilt binaries

download from GitHub releases.

nix

nix profile install github:ieviev/resharp-grep

or in a flake:

inputs.resharp.url = "github:ieviev/resharp-grep";

nix package includes shell completions.

how it works

all flags compile down to RE# patterns. for example:

re --near 5 -a unsafe -a unwrap

compiles to:

(_*unsafe_*) & (_*unwrap_*) & ~((_*\n_*){5})

each -a term becomes an intersection, --near 5 rejects spans containing 5+ newlines, and scopes add their own boundary. because everything shares the same pattern representation, all output modes (highlighting, context, --count, --json, etc.) work uniformly.

see the RE# engine for more on the pattern language.

Have fun!