
# Початок роботи

## Встановлення

Встановіть 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+** для класів лише для читання, переліків, синтаксису виклику функцій першого класу та просування властивостей конструктора
- **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()`. Про хостинги, які вимикають `proc_open()`, `shell_exec()` або `pcntl_fork()`, див. розділ [Хостинги з обмеженнями на процеси](https://greph.inline0.dev/uk/docs/advanced/process-restricted-hosts).

## Ваш перший текстовий пошук

Режим за замовчуванням у 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/uk/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/uk/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/uk/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/uk/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/uk/docs/indexed/text) і [Індексований / AST](https://greph.inline0.dev/uk/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/uk/docs/compatibility/rg) і [Сумісність / sg](https://greph.inline0.dev/uk/docs/compatibility/sg), а також у згенерованій [матриці можливостей](https://greph.inline0.dev/uk/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` для повторюваних структур із кількома індексами.
