
# Pesquisa de texto

O modo de texto de Greph faz uma pesquisa de bytes orientada a linhas em uma árvore de arquivos percorrida. É o modo padrão de `greph` CLI e da fachada `Greph::searchText()`. A saída usa o formato canônico `file:line:content`, interpretado por grep, ripgrep e pela maioria das integrações com editores.

## Exemplos rápidos

```bash
# Regex search across the current directory
./vendor/bin/greph "function\s+\w+"

# Fixed-string search across src/
./vendor/bin/greph -F "function" src

# Case-insensitive whole-word search
./vendor/bin/greph -F -i -w "function" src

# Two lines of context around each match
./vendor/bin/greph -F -C 2 "TODO" src

# Stop after the first three matches per file
./vendor/bin/greph -F -m 3 "TODO" src

# Files that contain the pattern
./vendor/bin/greph -F -l "TODO" src

# Files that do not contain the pattern
./vendor/bin/greph -F -L "TODO" src

# Count matches per file
./vendor/bin/greph -F -c "TODO" src

# Inverted match
./vendor/bin/greph -F -v "TODO" src/notes.txt
```

## Padrões

Por padrão, o padrão é tratado como uma expressão regular PCRE2. As funções de PHP `preg_*` dão suporte ao mecanismo, então a sintaxe corresponde à [referência do PCREPHP](https://www.php.net/manual/en/pcre.pattern.php).

Desative o mecanismo de regex com `-F` para tratar o padrão como uma sequência literal de bytes. O modo de string literal é o caminho rápido: usa `strpos()` para fazer a correspondência e ignora totalmente a etapa de compilação do PCRE2.

`-i` torna os dois modos insensíveis a maiúsculas e minúsculas. `-w` adiciona limites de palavra inteira em ambos os lados da correspondência.

## Filtragem de arquivos

Greph percorre a árvore de arquivos antes de pesquisar. O percurso é compartilhado pelos modos AST e indexado, então os mesmos sinalizadores de filtragem se aplicam a todos eles.

| Sinalizador | Efeito |
|---|---|
| `--type NAME` | Inclui apenas arquivos que correspondem ao alias de tipo indicado (`php`, `js`, `md`, ...) |
| `--type-not NAME` | Exclui arquivos que correspondem ao alias de tipo indicado |
| `--glob GLOB` | Inclui apenas arquivos cujos caminhos correspondem a GLOB. Pode ser repetido. |
| `--no-ignore` | Ignora `.gitignore` e `.grephignore` |
| `--hidden` | Inclui arquivos ocultos |

Por padrão, o percurso respeita `.gitignore` e `.grephignore`, ignora arquivos binários (detectados por bytes nulos nos primeiros 512 bytes) e limita o tamanho dos arquivos a 10 MiB. Os dois limites podem ser configurados por `WalkOptions`.

Consulte [API / FileTypeFilter](https://greph.inline0.dev/pt/docs/api#grephwalkerfiletypefilter) para ver a lista completa dos aliases de tipo integrados.

## Contexto, contagens e modos somente de arquivo

```bash
# Two lines before and after each match
./vendor/bin/greph -F -C 2 "needle" src

# Two lines after, no lines before
./vendor/bin/greph -F -A 2 "needle" src

# Two lines before, no lines after
./vendor/bin/greph -F -B 2 "needle" src

# Count matches per file
./vendor/bin/greph -F -c "needle" src

# List matching files only
./vendor/bin/greph -F -l "needle" src

# List non-matching files only
./vendor/bin/greph -F -L "needle" src
```

`-c`, `-l` e `-L` interrompem a execução do formatador antes que ele materialize todas as linhas. São os modos adequados para consultas de "quantos" e "onde".

## Varreduras paralelas

Passe `-j N` para distribuir a varredura entre N workers. Greph usa `pcntl_fork()` para o pool de workers e recorre à execução em processo único quando `ext-pcntl` não está disponível.

```bash
./vendor/bin/greph -F -j 8 "function" src
```

A fachada calcula se a execução paralela compensa o custo adicional com base na quantidade de arquivos, no modo e no formato do padrão. Abaixo do limite, permanece em processo único. Consulte [Avançado / Workers paralelos](https://greph.inline0.dev/pt/docs/advanced/parallel) para ver as heurísticas.

## Saída JSON

`--json` emite um conteúdo estruturado que ferramentas posteriores podem interpretar sem extrair informações da saída de grep:

```bash
./vendor/bin/greph --json -F "function" src
```

```json
[
  {
    "file": "src/Greph.php",
    "matches": [
      {
        "line": 31,
        "column": 1,
        "content": "final class Greph",
        "matched_text": "function",
        "captures": []
      }
    ]
  }
]
```

O wrapper `rg` emite um JSON estruturado como eventos ripgrep. Use-o quando um consumidor existente espera o esquema ripgrep.

## Uso programático

```php
use Greph\Greph;
use Greph\Text\TextSearchOptions;

$results = Greph::searchText(
    'function',
    'src',
    new TextSearchOptions(
        fixedString: true,
        caseInsensitive: true,
        beforeContext: 1,
        afterContext: 1,
        jobs: 4,
    ),
);

foreach ($results as $file) {
    foreach ($file->matches as $match) {
        echo "{$file->file}:{$match->line}:{$match->content}\n";
    }
}
```

Os objetos de resultado estão documentados em [API / Objetos de resultado](https://greph.inline0.dev/pt/docs/api#result-objects).

## Como funciona

O mecanismo de texto tem dois caminhos:

- **Caminho literal**: quando `-F` está definido, a pesquisa executa `strpos()` em um leitor com buffer de 64 KiB e acompanha as quebras de linha para numerar as linhas. Não há etapa de compilação de regex.
- **Caminho de regex**: quando `-F` não está definido, Greph extrai trechos literais do padrão usando um pequeno analisador no formato PCRE (`Greph\Text\LiteralExtractor`) e os usa como pré-filtro `strpos()`. Em seguida, as linhas aprovadas pelo pré-filtro são comparadas com o padrão PCRE2 compilado, com JIT ativado.

Os dois caminhos usam o mesmo `BufferedReader` para E/S. O leitor lê blocos de 64 KiB em vez de `fgets()` por linha, o que reduz drasticamente a quantidade de chamadas de sistema em arquivos grandes.

Para cargas de trabalho repetidas, o modo de texto indexado [indexado](https://greph.inline0.dev/pt/docs/indexed/text) substitui o leitor com buffer por um índice de trigramas e ocorrências de identificadores aquecido e ignora a maioria dos arquivos por completo.
