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.