
# Tekstsøgning

Grephs teksttilstand er en linjeorienteret bytesøgning i et gennemgået filtræ. Det er standardtilstanden for `greph` CLI og facaden `Greph::searchText()`. Output bruger det kanoniske format `file:line:content`, som grep, ripgrep og de fleste editorintegrationer kan fortolke.

## Hurtige eksempler

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

## Mønstre

Som standard behandles mønsteret som et PCRE2-regulært udtryk. Motoren bygger på funktionerne i PHPs `preg_*`, så syntaksen følger [PHP PCRE-referencen](https://www.php.net/manual/en/pcre.pattern.php).

Slå regex-motoren fra med `-F` for at behandle mønsteret som en bogstavelig bytesekvens. Tilstand med fast streng er den hurtige vej: Den bruger `strpos()` til matchning og springer helt over kompileringstrinnet for PCRE2.

`-i` gør begge tilstande ufølsomme over for store og små bogstaver. `-w` tilføjer grænser for hele ord på begge sider af matchet.

## Filtrering af filer

Greph gennemgår filtræet før søgningen. Filtræet deles med AST-tilstand og indekseret tilstand, så de samme filtreringsflag gælder overalt.

| Flag | Effekt |
|---|---|
| `--type NAME` | Medtag kun filer, der matcher det navngivne typealias (`php`, `js`, `md`, ...) |
| `--type-not NAME` | Udelad filer, der matcher det navngivne typealias |
| `--glob GLOB` | Medtag kun filer, hvis stier matcher GLOB. Kan gentages. |
| `--no-ignore` | Respekter ikke `.gitignore` eller `.grephignore` |
| `--hidden` | Medtag skjulte filer |

Filtræet respekterer som standard `.gitignore` og `.grephignore`, springer binære filer over (registreret via nullbytes i de første 512 bytes) og begrænser filstørrelsen til 10 MiB. Begge grænser kan konfigureres via `WalkOptions`.

Se [API / FileTypeFilter](https://greph.inline0.dev/da/docs/api#grephwalkerfiletypefilter) for den fulde liste over indbyggede typealiaser.

## Kontekst, antal og tilstande kun for filer

```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` og `-L` afbryder formateringen tidligt, så alle linjer ikke materialiseres. De er velegnede til forespørgsler om "hvor mange" og "hvor".

## Parallelle scanninger

Angiv `-j N` for at fordele scanningen på N arbejdere. Greph bruger `pcntl_fork()` til arbejdspuljen og går tilbage til enkeltproceskørsel, når `ext-pcntl` ikke er tilgængelig.

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

Facaden beregner, om parallel kørsel er besværet værd, ud fra antal filer, tilstand og mønsterets form. Under tærsklen forbliver den i enkeltproces. Se [Avanceret / Parallelle arbejdere](https://greph.inline0.dev/da/docs/advanced/parallel) for heuristikkerne.

## JSON-output

`--json` udsender en struktureret payload, som efterfølgende værktøjer kan fortolke uden at skærmskrabe grep-formatet:

```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": []
      }
    ]
  }
]
```

Wrapperen `rg` udsender i stedet ripgrep-hændelsesformede JSON. Brug den, når en eksisterende forbruger forventer skemaet ripgrep.

## Programmatisk brug

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

Resultatobjekterne er beskrevet i [API / Resultatobjekter](https://greph.inline0.dev/da/docs/api#result-objects).

## Sådan fungerer det

Tekstmotoren har to veje:

- **Bogstavelig vej**: Når `-F` er angivet, kører søgningen `strpos()` over en bufferlæser på 64 KiB og holder styr på linjeskift til linjenummerering. Der er intet regex-kompileringstrin.
- **Regex-vej**: Når `-F` ikke er angivet, udtrækker Greph bogstavelige delstrenge fra mønsteret ved hjælp af en lille PCRE-formet analysator (`Greph\Text\LiteralExtractor`) og bruger dem som et `strpos()`-forfilter. Linjer, der passerer forfilteret, matches derefter mod det kompilerede PCRE2-mønster med JIT aktiveret.

Begge veje bruger samme `BufferedReader` til I/O. Læseren læser i bidder på 64 KiB i stedet for `fgets()` pr. linje, hvilket reducerer antallet af systemkald markant i store filer.

Ved gentagne arbejdsbelastninger erstatter [indekseret teksttilstand](https://greph.inline0.dev/da/docs/indexed/text) bufferlæseren med et opvarmet trigram- og identifikatorindeks og springer helt over de fleste filer.
