
# Aan de slag

## Installatie

Installeer Greph via Composer:

```bash
composer require greph/greph
```

Hiermee worden de bibliotheek en vier uitvoerbare bestanden geïnstalleerd in `vendor/bin/`:

- `greph`: native tekst zoeken, AST zoeken en AST herschrijven
- `greph-index`: opgewarmde tekstindex, AST-feitenindex en gecachte AST-zoekopdracht
- `rg`: compatibiliteitswrapper in de stijl van ripgrep
- `sg`: compatibiliteitswrapper in de stijl van ast-grep

Deze uitvoerbare bestanden werken vanuit de `vendor/bin/` van je project, omdat Greph 0.2.3. Eerdere versies vonden de autoloader Composer alleen binnen een kloon van de repository Greph; gebruik daarom ten minste die versie:

```bash
composer require greph/greph:^0.2.3
```

## Vereisten

- **PHP 8.2+** voor readonly-klassen, enums, first-class callable-syntaxis en constructorpromotie
- **ext-json** voor JSON-uitvoer en indexpayloads op schijf
- **ext-ctype** voor patroon- en optieparsing
- **ext-tokenizer** voor PHP-Parser en de AST-prefilters
- **ext-zlib** voor de gecachte AST-opslag (`greph-index ast-cache`)
- **nikic/php-parser** (automatisch geïnstalleerd als afhankelijkheid van Composer)

`ext-json`, `ext-ctype` en `ext-tokenizer` zijn in bijna elke PHP-build ingeschakeld. `composer.json` declareert momenteel alleen `ext-json` ([#5](https://github.com/inline0/greph/issues/5)), dus Composer geeft geen waarschuwing als een van de andere ontbreekt.

Optioneel:

- **ext-pcntl** voor parallelle scans. Greph schakelt bij ontbreken probleemloos over op uitvoering met één proces.
- Externe binaire bestanden van `rg`, `grep` en `sg` voor benchmarkvergelijkingen. Ze zijn tijdens runtime nooit vereist.

Zoeken, herschrijven en indexeren roepen nooit `proc_open()` of `shell_exec()` aan; alleen parallelle scans forken processen en vallen zonder `pcntl_fork()` terug op één proces. Zie [Hosts met procesbeperkingen](https://greph.inline0.dev/nl/docs/advanced/process-restricted-hosts) voor hosts die `proc_open()`, `shell_exec()` of `pcntl_fork()` uitschakelen.

## Je eerste tekstzoekopdracht

De standaardmodus van Greph is tekst zoeken op een manier die compatibel is met grep:

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

De uitvoer gebruikt de canonieke `file:line:content`-indeling die grep, ripgrep en de meeste editorintegraties verwachten.

```text
src/Greph.php:41:    public static function walk(string|array $paths, ?WalkOptions $options = null): FileList
src/Greph.php:50:    public static function searchText(string $pattern, string|array $paths, ?TextSearchOptions $options = null): array
src/Greph.php:81:    public static function buildTextIndex(
```

Voeg `-i` toe voor hoofdletterongevoelig zoeken, `-w` voor hele woorden, `-c` voor aantallen, `-l` voor alleen bestandspaden, `-C 2` voor twee regels context, enzovoort. De volledige lijst staat in de referentie [CLI](https://greph.inline0.dev/nl/docs/cli).

## Je eerste AST-zoekopdracht

Geef `-p` en een patroon in de vorm van PHP door om over te schakelen op structureel zoeken:

```bash
vendor/bin/greph -p 'new $CLASS()' src
```

`$CLASS` is een metavariabele die elke klassenaam vastlegt. Het patroon `new $CLASS()` komt overeen met elke expressie van `new` zonder argumenten, ongeacht klasse, opmaak of opmerkingen. Gebruik `new $CLASS($$$ARGS)` om aanroepen met willekeurige argumenten te vinden.

Elke AST-match wordt weergegeven als bestand, beginregel en overeenkomende code:

```text
src/Greph.php:43:new FileWalker()
src/Greph.php:52:new TextSearchOptions()
src/Greph.php:54:new TextSearcher()
```

Andere nuttige patronen:

```bash
# Any method call with any arguments
vendor/bin/greph -p '$obj->$method($$$ARGS)' src

# Any function declaration with a void return type
vendor/bin/greph -p 'function $name($$$PARAMS): void {}' src

# Old-style array calls
vendor/bin/greph -p 'array($$$ITEMS)' src
```

Zie [Modi / AST Search](https://greph.inline0.dev/nl/docs/modes/ast) voor de volledige patroonsyntaxis.

## Je eerste herschrijving

Voeg `-r` toe om van de AST-zoekopdracht een herschrijving te maken:

```bash
# Preview only
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --dry-run src

# Apply
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' src

# Confirm each file before writing
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --interactive src
```

Bij herschrijvingen blijft de opmaak buiten de match behouden: alleen het overeenkomende knooppunt wordt vervangen en de omliggende witruimte, inspringing en opmerkingen blijven intact. Het knooppunt zelf wordt opnieuw opgemaakt op basis van de sjabloon, waardoor de indeling ervan wordt genormaliseerd en een opmerking erin verloren kan gaan. Zie [Modi / Rewrite](https://greph.inline0.dev/nl/docs/modes/rewrite) voor meer informatie.

## PHP API

De statische `Greph\Greph`-facade biedt dezelfde bewerkingen als de CLI:

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

$results = Greph::searchText(
    'function',
    'src',
    new TextSearchOptions(fixedString: true, caseInsensitive: true),
);

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

$matches = Greph::searchAst(
    'new $CLASS()',
    'src',
    new AstSearchOptions(),
);

foreach ($matches as $match) {
    echo "{$match->file}:{$match->startLine}:{$match->code}\n";
}
```

Het volledige aanbod wordt beschreven in [API](https://greph.inline0.dev/nl/docs/api).

## Geïndexeerd zoeken

Herhaalde taken profiteren van opgewarmde indexen. Bouw de index één keer en voer daarna veel zoekopdrachten uit:

```bash
# Text index
vendor/bin/greph-index build .
vendor/bin/greph-index search -F "function" .

# AST fact index
vendor/bin/greph-index ast-index build .
vendor/bin/greph-index ast-index search 'new $CLASS()' src

# Cached parsed-tree index
vendor/bin/greph-index ast-cache build .
vendor/bin/greph-index ast-cache search 'array($$$ITEMS)' src
```

Indexen staan standaard in `.greph-index`, `.greph-ast-index` en `.greph-ast-cache` in de projectroot.

Kies voor actief veranderende mappenstructuren een levenscyclusprofiel in plaats van elke opgewarmde index hetzelfde te behandelen:

```bash
vendor/bin/greph-index build . --lifecycle static
vendor/bin/greph-index build . \
  --lifecycle opportunistic-refresh \
  --auto-refresh-max-files 32 \
  --auto-refresh-max-bytes 1048576
vendor/bin/greph-index stats . --dry-refresh
```

Het gebruikelijke patroon is:

- behoud een stabiele basis als `static`
- houd actief veranderende overlays bij als `opportunistic-refresh`
- inspecteer verouderd gedrag met `stats --dry-refresh`

### Zoeken in meerdere opgewarmde indexen

Je kunt met één opdracht in meerdere opgewarmde indexen zoeken:

```bash
vendor/bin/greph-index search -F "apply_filters" . \
  --index-dir wordpress/.greph-index \
  --index-dir wp-content/plugins/my-plugin/.greph-index \
  --show-index-origin

vendor/bin/greph-index ast-index search 'new $CLASS()' . \
  --index-dir wordpress/.greph-ast-index \
  --index-dir wp-content/plugins/my-plugin/.greph-ast-index \
  --show-index-origin
```

### Benoemde indexsets

Als je dit regelmatig doet, zet de indeling dan in `.greph-index-set.json` en gebruik de set-subopdrachten in plaats van de opties telkens opnieuw op te geven:

```bash
vendor/bin/greph-index set build
vendor/bin/greph-index set stats --dry-refresh
vendor/bin/greph-index set search --show-index-origin -F "apply_filters" .
vendor/bin/greph-index set search --mode ast-index 'new $CLASS()' .
vendor/bin/greph-index set search --mode ast-cache 'array($$$ITEMS)' .
```

### Plannertracering

Voeg `--trace-plan` toe om te zien hoe zoeken met opgewarmde indexen de kandidaten beperkt:

```bash
vendor/bin/greph-index search --trace-plan -F "function" .
vendor/bin/greph-index ast-index search --trace-plan 'new $CLASS()' .
```

Zie [Geïndexeerd / Tekst](https://greph.inline0.dev/nl/docs/indexed/text) en [Geïndexeerd / AST](https://greph.inline0.dev/nl/docs/indexed/ast) voor de volledige workflow met opgewarmde indexen.

## Compatibiliteitswrappers

Als je tools of agents hebt die al met ripgrep of ast-grep werken, kun je de wrappers direct gebruiken:

```bash
vendor/bin/rg --json -F "function" src
vendor/bin/sg --pattern 'new $CLASS()' src --lang php
```

Beide wrappers gebruiken dezelfde engine en zijn met probes gecontroleerd aan de hand van de upstream-binaire bestanden. De gecontroleerde functionaliteit wordt beschreven in [Compatibiliteit / rg](https://greph.inline0.dev/nl/docs/compatibility/rg) en [Compatibiliteit / sg](https://greph.inline0.dev/nl/docs/compatibility/sg) en is opgenomen in de gegenereerde [functiematrix](https://greph.inline0.dev/nl/docs/advanced/feature-matrix).

## Configuratie

Greph herkent twee conventies voor bestanden op schijf:

- `.gitignore`: wordt standaard gerespecteerd. Geef `--no-ignore` door om dit uit te schakelen.
- `.grephignore`: dezelfde syntaxis als `.gitignore`, daar bovenop toegepast. Handig voor tool-specifieke uitsluitingen die je niet in versiebeheer wilt opnemen.

De standaardmappen voor indexen zijn `.greph-index`, `.greph-ast-index` en `.greph-ast-cache` in de gekozen root. Stel een andere map in met `--index-dir` bij elke `greph-index`-subopdracht, of gebruik `.greph-index-set.json` voor herhaalbare indelingen met meerdere indexen.
