The content verb
rf content <pattern> [path] [--json]
content searches file contents for pattern under path (default .). It
runs the search once per filter layer and attributes each newly surfaced file to
the layer that had hidden it.
The layers
The layers are cumulative — each one relaxes an additional default filter, in the order ripgrep applies them:
surfaced_by |
What it means | Confirm with |
|---|---|---|
default |
Found by a plain search; nothing hid it | rg 'pattern' . |
vcs_ignore |
Hidden by .gitignore / .ignore rules |
rg -u 'pattern' . |
hidden |
A hidden file or dotfile | rg -uu 'pattern' . |
binary |
A file ripgrep detects as binary | rg -uu -a 'pattern' . |
case |
Matched only when case is ignored | rg -i 'pattern' . |
Binary detection replicates ripgrep exactly: quit-on-NUL unless binary-as-text
is requested. .git internals are never treated as content, so commit messages
and reflogs never show up as spurious matches.
The encoding probe
encoding_utf16 is not a cumulative layer — it is a parallel probe. Forcing
a UTF-16 decoder makes ripgrep misread every UTF-8 file, which would hide the
matches the other layers found. So rf runs the UTF-16 decode against its own
base and keeps only the files that decoder alone surfaces, never disturbing the
cumulative layers.
Warnings and commands
Each miss adds a warning with a stable code — IGNORE_VCS, HIDDEN_SKIPPED,
BINARY_SKIPPED, CASE_SENSITIVE, or ENCODING_MISS — and the paste-ready
rg command that reproduces it. The full list is in
the JSON contract and under rf capabilities.
Example
rf content MAGIC_TOKEN . --json
{
"ok": true,
"data": [
{ "file": "src/app.py", "surfaced_by": "default" },
{ "file": ".env", "surfaced_by": "hidden" },
{ "file": "build/out.min.js", "surfaced_by": "vcs_ignore" }
],
"meta": { "matched_files": 3, "default_matched_files": 1, "hidden_by_filters": 2 }
}
An absent term returns exit 0 with data: [] — see Exit codes.