
# Първи стъпки

## Инсталиране

Инсталирайте Greph чрез Composer:

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

Това инсталира библиотеката и четири изпълними файла в `vendor/bin/`:

- `greph`: търсене в обикновен текст, AST търсене и AST пренаписване
- `greph-index`: загрят текстов индекс, индекс на AST факти и кеширано AST търсене
- `rg`: обвивка за съвместимост в стил ripgrep
- `sg`: обвивка за съвместимост в стил ast-grep

Тези изпълними файлове работят от директорията `vendor/bin/` на проекта ви, тъй като Greph 0.2.3. По-ранните версии намираха автоматично зареждащия файл Composer само в клонирано хранилище Greph, затова използвайте поне тази версия:

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

## Изисквания

- **PHP 8.2+** за readonly класове, enum-и, синтаксис за callable обекти от първи клас и промотиране на параметри в конструктора
- **ext-json** за JSON изход и полезни данни на индекса на диска
- **ext-ctype** за разчитане на шаблони и опции
- **ext-tokenizer** за PHP-Parser и предварителните филтри на AST
- **ext-zlib** за кешираното хранилище на AST (`greph-index ast-cache`)
- **nikic/php-parser** (инсталира се автоматично като зависимост на Composer)

`ext-json`, `ext-ctype` и `ext-tokenizer` са активирани в почти всяка компилация на PHP. `composer.json` декларира засега само `ext-json` ([#5](https://github.com/inline0/greph/issues/5)), затова Composer не предупреждава, ако някоя от останалите липсва.

Незадължително:

- **ext-pcntl** за паралелни сканирания. Greph преминава безпроблемно към изпълнение в един процес, ако липсва.
- Външни двоични файлове на `rg`, `grep` и `sg` за сравнения в бенчмаркове. Те никога не са необходими по време на изпълнение.

Търсенето, пренаписването и индексирането никога не извикват `proc_open()` или `shell_exec()`; само паралелните сканирания създават дъщерни процеси и преминават към един процес без `pcntl_fork()`. Вижте [Хостове с ограничени процеси](https://greph.inline0.dev/bg/docs/advanced/process-restricted-hosts) за хостове, които забраняват `proc_open()`, `shell_exec()` или `pcntl_fork()`.

## Първото ви търсене на текст

Режимът по подразбиране на Greph е текстово търсене, съвместимо с grep:

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

Изходът използва каноничния формат `file:line:content`, очакван от grep, ripgrep и повечето интеграции с редактори.

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

Добавете `-i` за съвпадение без значение от регистъра, `-w` за цели думи, `-c` за брой съвпадения, `-l` само за файлови пътища, `-C 2` за два реда контекст и т.н. Пълният списък е в [справочника за CLI](https://greph.inline0.dev/bg/docs/cli).

## Първото ви търсене в AST

Подайте `-p` и шаблон във формат PHP, за да преминете към структурно търсене:

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

`$CLASS` е метапроменлива, която съвпада с произволно име на клас. Шаблонът `new $CLASS()` съвпада с всеки израз `new` без аргументи, независимо от класа, форматирането или коментарите. Използвайте `new $CLASS($$$ARGS)`, за да съвпадат извиквания с произволни аргументи.

Всяко съвпадение в AST се извежда като файл, начален ред и съвпаднал код:

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

Други полезни шаблони:

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

Вижте [Режими / Търсене в AST](https://greph.inline0.dev/bg/docs/modes/ast) за пълния синтаксис на шаблоните.

## Първото ви пренаписване

Добавете `-r`, за да превърнете търсенето в AST в пренаписване:

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

Пренаписванията запазват форматирането извън съвпадението: заменя се само съвпадналият възел, а околните интервали, отстъпи и коментари остават непроменени. Самият съвпаднал възел се генерира наново от шаблона, затова оформлението му се нормализира и коментар в него може да се загуби. Вижте [Режими / Пренаписване](https://greph.inline0.dev/bg/docs/modes/rewrite) за подробности.

## PHP API

Статичният фасад `Greph\Greph` предоставя същите операции като 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";
}
```

Пълният набор от възможности е описан в [API](https://greph.inline0.dev/bg/docs/api).

## Индексирано търсене

Повтарящите се задачи печелят от предварително заредени индекси. Създайте индекс веднъж и после правете много заявки:

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

По подразбиране индексите се съхраняват в `.greph-index`, `.greph-ast-index` и `.greph-ast-cache` в основната директория на проекта.

За дървета, които се променят активно, изберете профил за жизнения цикъл, вместо да третирате всички предварително заредени индекси еднакво:

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

Обичайният подход е:

- поддържайте стабилната основа като `static`
- поддържайте активно променящите се наслагвания като `opportunistic-refresh`
- проверявайте остарялото състояние с `stats --dry-refresh`

### Търсене в няколко индекса

Можете да търсите в няколко предварително заредени индекса с една команда:

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

### Наименувани набори от индекси

Ако правите това многократно, задайте оформлението в `.greph-index-set.json` и използвайте подкомандите за набори, вместо да повтаряте флагове:

```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)' .
```

### Проследяване на планировчика

За да видите как предварително зареденото търсене стеснява набора от кандидати, добавете `--trace-plan`:

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

Вижте [Индексирано / Текст](https://greph.inline0.dev/bg/docs/indexed/text) и [Индексирано / AST](https://greph.inline0.dev/bg/docs/indexed/ast) за пълния работен процес с предварително заредени индекси.

## Обвивки за съвместимост

Ако вече имате инструменти или агенти, които използват ripgrep или ast-grep, добавете съответните обвивки:

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

Двете обвивки използват същия енджин и са проверени чрез сондиране спрямо оригиналните двоични файлове. Проверените възможности са описани в [Съвместимост / rg](https://greph.inline0.dev/bg/docs/compatibility/rg) и [Съвместимост / sg](https://greph.inline0.dev/bg/docs/compatibility/sg) и са представени отново в генерираната [матрица на функциите](https://greph.inline0.dev/bg/docs/advanced/feature-matrix).

## Конфигурация

Greph разпознава две конвенции за файлове на диска:

- `.gitignore`: спазва се по подразбиране. Подайте `--no-ignore`, за да го изключите.
- `.grephignore`: същият синтаксис като `.gitignore`, прилаган отгоре. Полезно за специфични за инструмента изключения, които не искате да включвате в контрола на версиите.

По подразбиране директориите за индекси са `.greph-index`, `.greph-ast-index` и `.greph-ast-cache` в избрания корен. Заменете настройката с `--index-dir` във всяка подкоманда на `greph-index` или използвайте `.greph-index-set.json` за повторяеми оформления с няколко индекса.
