Laravel explorer style prompt based on larave/prompts package. Build CLI table based explorers easily.
composer require knobik/explorer-prompt
use function Knobik\Prompts\explorer;
$result = explorer(
items: [
[1, 'John Doe', '[email protected]'],
[2, 'Jane Doe', '[email protected]'],
[3, 'Jan Kowalski', '[email protected]'],
],
title: 'Hello from a explorer window',
header: [
'ID',
'Name',
'Email',
],
)
->prompt();
You can filter on your data by pressing forward slash /
.
Filtering prompt can be disabled by using disableFiltering
method.
You can also create your custom filtering solution by providing a invokable class or function to the setFilterHandler
method. Example class:
use Knobik\Prompts\ExplorerPrompt;
class FilterHandler
{
public function __invoke(ExplorerPrompt $prompt, string $filter): array
{
if ($filter === '') {
return $prompt->items;
}
return collect($prompt->items)
->filter(function ($item) use ($prompt, $filter) {
$item = is_array($item) ? $item : [$item];
foreach (array_values($item) as $index => $column) {
if ($prompt->getColumnFilterable($index) && str_contains($column, $filter)) {
return true;
}
}
return false;
})
->toArray();
}
}
use Knobik\Prompts\Key;
use function Knobik\Prompts\explorer;
function getDirectoryFiles(string $path): array
{
$files = collect(glob("{$path}/*"))
->mapWithKeys(function (string $filename) {
return [
$filename => [
'filename' => basename($filename),
'size' => filesize($filename),
'permissions' => sprintf('%o', fileperms($filename)),
]
];
});
if ($path !== '/') {
$files->prepend([
'filename' => '..',
'size' => null,
'permissions' => sprintf('%o', fileperms(dirname($path)))
], dirname($path));
}
return $files->toArray();
}
$path = '/var/www/html';
while (true) {
$newPath = explorer(
items: $this->getDirectoryFiles($path),
title: $path, //fn(ExplorerPrompt $prompt) => $prompt->highlighted,
header: [
'File name',
'Size in bytes',
'Permissions'
],
)
->setCustomKeyHandler(Key::KEY_ESCAPE, function(ExplorerPrompt $prompt, string $key) { // custom key handler
$prompt->cancel();
})
->setColumnOptions(
column: 2,
width: 20, // number of characters, null to keep it in auto mode
align: ColumnAlign::RIGHT,
filterable: false
)
->prompt();
if ($newPath === null) {
continue; // no item selected
}
$path = $newPath;
if (is_file($path)) {
$this->line(file_get_contents($path));
return self::SUCCESS;
}
}