Skip to content

Add content-search predicates: -content/-icontent (literal) + -rxc/-irxc (regex) - #195

Merged
helly25 merged 3 commits into
mainfrom
feat/grep-content-predicate
Jun 28, 2026
Merged

Add content-search predicates: -content/-icontent (literal) + -rxc/-irxc (regex)#195
helly25 merged 3 commits into
mainfrom
feat/grep-content-predicate

Conversation

@helly25

@helly25 helly25 commented Jun 28, 2026

Copy link
Copy Markdown
Owner

File-content search (ripgrep/fd parity): the xff counterpart of -name/-regex, but over a file's bytes instead of its path.

predicate matches
-content STR a literal substring of the content
-icontent STR -content, ASCII case-folded
-rxc RE an RE2 regular expression, unanchored (PartialMatch)
-irxc RE -rxc, case-insensitive

All four are xff extensions (--config=find rejects them) and Cost::kExpensive (they read the file). Binary files are skipped by default via a NUL-byte sniff over the first 8 KiB (grep/ripgrep behaviour).

Naming

-grep was deliberately rejected: grep's BRE/ERE/-P flavor baggage makes it ambiguous for both a literal and a single-flavor-regex predicate. -content is unambiguous; -rxc (rx=regex, c=content) sidesteps "which grep regex?" entirely.

Mechanism

  • regex::Matcher::PartialMatch (RE2 PartialMatch), backing -rxc/-irxc.
  • vfs::FileSystem::ReadContent (whole-file read) across all implementers: LocalFs POSIX read loop, DryRunFileSystem delegates, the test fakes stub it.
  • evaluate.cc ContentToSearch (type-gate + read + binary sniff) + EvalContent/EvalRxc.
  • parser CompileNodeRegex precompiles -rxc/-irxc like -regex/-iregex.

Self-documentation (registry SOT, same change)

Four Descriptor summaries flow into --help / --help=NAME / --man / --markdown; the kHelpText expression summary is updated; docs/design.md records the resolved names, superseding the -contains/-grep placeholders.

Tests

  • regex_test: PartialMatch (unanchored vs FullMatch).
  • local_fs_test: ReadContent bytes + missing-path error.
  • evaluate_test: literal / regex / case-fold / binary-skip / non-regular + missing.
  • content_test.sh: end-to-end through the binary, incl. find-style gating and the --help=-content topic.

bazel test //... green (29 tests).

helly25 added 2 commits June 28, 2026 14:31
The plain renderer can now C-escape path bytes so a newline or control
character in a filename cannot corrupt the line-oriented -print stream:
--path-encoding=escape turns `\` and control bytes into `\\`, `\n`, `\t`,
`\r`, or `\xNN`; raw (the default) stays verbatim and find-compatible. It
applies to the plain format only -- kNul keeps raw bytes (the NUL is the
separator) and kJsonl always JSON-escapes.

render::Renderer gains a PathEncoding; run.cc ResolvePathEncoding mirrors
ResolveFormat (last wins, raw default) and feeds the implicit-print renderer.
Self-documented via the globals table + kHelpText (so --help/--man/--markdown
list it). render_test covers escape/raw and that it applies only to plain.

The other half of #45 (--exact, filesystem-native matching) remains.
…rxc (regex)

File-content search (rg/fd parity): the xff counterpart of -name/-regex, but over
a file's bytes instead of its path.

  -content STR / -icontent STR   literal substring (i = ASCII case-fold)
  -rxc RE / -irxc RE             RE2 regex, unanchored (PartialMatch)

All four are xff extensions (--config=find rejects them) and Cost::kExpensive (they
read the file). Binary files are skipped by default via a NUL-byte sniff over the
first 8 KiB (grep/ripgrep behaviour). The name -grep was deliberately rejected:
grep's BRE/ERE/-P flavor baggage is ambiguous for both a literal and a
single-flavor-regex predicate.

Mechanism:
- regex::Matcher::PartialMatch (RE2::PartialMatch), backing -rxc/-irxc.
- vfs::FileSystem::ReadContent (whole-file read) across all implementers: LocalFs
  uses a POSIX read loop, DryRunFileSystem delegates, the test fakes stub it.
- evaluate.cc ContentToSearch (type-gate + read + binary sniff) + EvalContent/EvalRxc.
- parser CompileNodeRegex precompiles -rxc/-irxc like -regex/-iregex.

Self-documentation in the same change (registry SOT): four Descriptor summaries
(flow into --help / --help=NAME / --man / --markdown), the kHelpText expression
summary, and a resolved-names note in docs/design.md superseding the
-contains/-grep placeholders.

Tests: regex PartialMatch; LocalFs::ReadContent; evaluate_test literal / regex /
case-fold / binary-skip / non-regular; content_test.sh end-to-end (incl. find-style
gating and the --help topic).
@helly25
helly25 enabled auto-merge (squash) June 28, 2026 14:13
@helly25
helly25 merged commit 443b7fc into main Jun 28, 2026
8 checks passed
@helly25
helly25 deleted the feat/grep-content-predicate branch June 28, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant