
# Textové vyhledávání

Textový režim Greph prohledává procházený strom souborů po řádcích a bajtech. Jde o výchozí režim `greph` CLI i rozhraní `Greph::searchText()`. Výstup používá kanonický formát `file:line:content`, který zpracovávají grep, ripgrep i většina integrací do editorů.

## Rychlé příklady

```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
```

## Vzory

Ve výchozím nastavení se se vzorem zachází jako s regulárním výrazem PCRE2. O běh enginu se starají funkce `preg_*` nástroje PHP, takže syntaxe odpovídá [referenci PCRE PHP](https://www.php.net/manual/en/pcre.pattern.php).

Vypnutím enginu regulárních výrazů pomocí `-F` se vzorem zachází jako s doslovnou sekvencí bajtů. Režim pevných řetězců je rychlejší: k porovnávání používá `strpos()` a zcela vynechává kompilaci PCRE2.

`-i` zajistí, že oba režimy nerozlišují velikost písmen. `-w` přidá na obě strany shody hranice celého slova.

## Filtrování souborů

Greph před vyhledáváním projde strom souborů. Používá stejného procházeče jako režim AST a indexovaný režim, takže se všude uplatňují stejné příznaky filtrování.

| Příznak | Účinek |
|---|---|
| `--type NAME` | Zahrne pouze soubory odpovídající pojmenovanému aliasu typu (`php`, `js`, `md`, ...) |
| `--type-not NAME` | Vyloučí soubory odpovídající pojmenovanému aliasu typu |
| `--glob GLOB` | Zahrne pouze soubory, jejichž cesty odpovídají GLOB. Lze opakovat. |
| `--no-ignore` | Nebude respektovat `.gitignore` ani `.grephignore` |
| `--hidden` | Zahrne skryté soubory |

Procházeč ve výchozím nastavení respektuje `.gitignore` a `.grephignore`, přeskakuje binární soubory (rozpoznané podle nulových bajtů v prvních 512 bajtech) a omezuje velikost souboru na 10 MiB. Oba limity lze nastavit pomocí `WalkOptions`.

Úplný seznam vestavěných aliasů typů najdete v [API / FileTypeFilter](https://greph.inline0.dev/cs/docs/api#grephwalkerfiletypefilter).

## Kontext, počty a režimy pouze pro soubory

```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` a `-L` obejdou formátovač, takže není nutné načítat všechny řádky do paměti. Hodí se pro dotazy „kolik“ a „kde“.

## Paralelní prohledávání

Pomocí `-j N` rozdělíte prohledávání mezi N pracovníků. Greph používá pro fond pracovníků `pcntl_fork()` a přejde na jed proces, pokud `ext-pcntl` není k dispozici.

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

Rozhraní samo vyhodnotí, zda se paralelní zpracování vyplatí vzhledem k režii, počtu souborů, režimu a tvaru vzoru. Pod stanovenou hranicí zůstane u jednoho procesu. Heuristiky popisuje část [Pokročilé / Paralelní pracovníci](https://greph.inline0.dev/cs/docs/advanced/parallel).

## Výstup JSON

`--json` vytváří strukturovaný obsah, který mohou navazující nástroje zpracovat bez snímání textu ve formátu 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": []
      }
    ]
  }
]
```

Obalovací vrstva `rg` místo toho vytváří JSON ve tvaru událostí ripgrep. Použijte ji, pokud stávající příjemce očekává schéma ripgrep.

## Programové použití

```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";
    }
}
```

Objekty výsledků jsou popsány v části [API / Objekty výsledků](https://greph.inline0.dev/cs/docs/api#result-objects).

## Jak to funguje

Textový engine má dvě cesty:

- **Doslovná cesta**: Je-li nastavena hodnota `-F`, vyhledávání probíhá pomocí `strpos()` nad bufferovanou čtečkou o velikosti 64 KiB, která sleduje nové řádky pro číslování řádků. Žádný regulární výraz se nekompiluje.
- **Cesta regulárních výrazů**: Pokud není nastavena hodnota `-F`, Greph pomocí jednoduchého analyzátoru ve tvaru PCRE (`Greph\Text\LiteralExtractor`) extrahuje ze vzoru doslovné podřetězce a použije je jako předběžný filtr `strpos()`. Řádky, které filtrem projdou, se následně porovnají se zkompilovaným vzorem PCRE2 se zapnutým JIT.

Obě cesty pro vstup a výstup používají stejnou `BufferedReader`. Čtečka načítá data po 64 KiB blocích místo `fgets()` na řádek, což u velkých souborů výrazně snižuje počet systémových volání.

Při opakovaném použití [indexovaný textový režim](https://greph.inline0.dev/cs/docs/indexed/text) nahrazuje bufferovanou čtečku zahřátým úložištěm trigramů a výskytů identifikátorů a většinu souborů zcela přeskočí.
