TNNBD7ZMNCA3L6DV2DKBC2KHOAQZM3D6OUYRYQBUF4CVTUK6AR3QC ->assertExitCode(0);});it('shows live suggestions starting from all tags when prompted for a query', function () {Process::fake(function (PendingProcess $process) {return match ($process->command) {['pijul', 'log', '--output-format', 'json'] => Process::result(json_encode([['message' => 'feat(pijul-qol): first'],['message' => 'feat(pijul-qol:move-to-zero): second'],['message' => 'fix(cli): third'],], JSON_THROW_ON_ERROR)),default => Process::result('', 'Unexpected command.', 1),};});LiveSuggestPrompt::fake(['z', 'e', 'r', 'o', Key::ENTER]);$this->artisan('pijul:search-intent-tags')->expectsOutput('feat(pijul-qol:move-to-zero)')
it('renders initial live suggestions before any query is typed', function () {LiveSuggestPrompt::fake();$prompt = new LiveSuggestPrompt(label: 'Search query',options: fn (string $value): array => $value === ''? ['feat(pijul-qol)', 'feat(pijul-qol:move-to-zero)', 'fix(cli)']: ['fix(cli)'],placeholder: 'Type to filter intent tags...',scroll: 10,required: 'Please provide a search query.',);$output = (new LiveSuggestPromptRenderer($prompt))($prompt);expect(preg_replace("/\e\[[0-9;?]*[A-Za-z]/", '', $output))->toContain('feat(pijul-qol)')->toContain('fix(cli)');});it('returns all tags when the live filter has no input yet', function () {$command = app(App\Commands\PijulSearchIntentTagsCommand::class);$method = new ReflectionMethod($command, 'suggestedTags');$method->setAccessible(true);expect($method->invoke($command, ['feat(pijul-qol)','feat(pijul-qol:move-to-zero)','fix(cli)',], ''))->toBe(['feat(pijul-qol)','feat(pijul-qol:move-to-zero)','fix(cli)',]);});
<?phpnamespace App\Prompts\Renderers;use Laravel\Prompts\SuggestPrompt;use Laravel\Prompts\Themes\Default\SuggestPromptRenderer;class LiveSuggestPromptRenderer extends SuggestPromptRenderer{protected function renderOptions(SuggestPrompt $prompt): string{if (empty($prompt->matches())) {return '';}return implode(PHP_EOL, $this->scrollbar(array_map(function ($label, $key) use ($prompt) {$label = $this->truncate($label, $prompt->terminal()->cols() - 12);return $prompt->highlighted === $key? "{$this->cyan('›')} {$label} ": " {$this->dim($label)} ";}, $visible = $prompt->visible(), array_keys($visible)),$prompt->firstVisible,$prompt->scroll,count($prompt->matches()),min($this->longest($prompt->matches(), padding: 4), $prompt->terminal()->cols() - 6),$prompt->state === 'cancel' ? 'dim' : 'cyan'));}}
<?phpnamespace App\Prompts;use Laravel\Prompts\SuggestPrompt;class LiveSuggestPrompt extends SuggestPrompt{}
$query = trim((string) $this->ask('Search query'));
$query = trim((string) (new LiveSuggestPrompt(label: 'Search query',options: fn (string $value): array => $this->suggestedTags($tags, $value),placeholder: 'Type to filter intent tags...',scroll: self::LIVE_RESULTS_SCROLL,required: 'Please provide a search query.',hint: 'Results update on each keypress. Use arrows to scroll, then press Enter.',))->prompt());
/*** @param list<string> $tags* @return list<string>*/private function suggestedTags(array $tags, string $query): array{$query = trim($query);if ($query === '') {return array_values($tags);}return array_values(array_filter($tags,fn (string $tag): bool => str_contains(strtolower($tag), strtolower($query)),));}