55 lines
1.4 KiB
PHP
55 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace NoccyLabs\React\Shell;
|
|
|
|
use Evenement\EventEmitterInterface;
|
|
use Evenement\EventEmitterTrait;
|
|
use React\EventLoop\Loop;
|
|
|
|
class CommandHandler implements EventEmitterInterface
|
|
{
|
|
|
|
use EventEmitterTrait;
|
|
|
|
private array $commands = [];
|
|
|
|
private bool $allowAbbreviatedCommands = true;
|
|
|
|
public function add(string $command, callable $handler, array $signature=[]): self
|
|
{
|
|
$this->commands[$command] = [ 'handler' => $handler, 'signature' => $signature ];
|
|
return $this;
|
|
}
|
|
|
|
public function __invoke(array $line, Shell $shell)
|
|
{
|
|
$this->execute($line, $shell);
|
|
}
|
|
|
|
public function execute(array $line, Shell $shell)
|
|
{
|
|
$command = array_shift($line);
|
|
|
|
if ($this->allowAbbreviatedCommands) {
|
|
$candidates = array_filter(
|
|
array_keys($this->commands),
|
|
fn($c)=>str_starts_with($c,$command)
|
|
);
|
|
if (count($candidates)>1) {
|
|
$this->emit("candidates", [ $candidates, $shell ]);
|
|
return;
|
|
}
|
|
if (count($candidates)==1) {
|
|
$command = array_shift($candidates);
|
|
}
|
|
}
|
|
if (!array_key_exists($command, $this->commands)) {
|
|
$this->emit("command", [ $command, $line, $shell ]);
|
|
return;
|
|
}
|
|
|
|
Loop::futureTick(fn() => call_user_func($this->commands[$command]['handler'], $line, $shell));
|
|
|
|
}
|
|
}
|