Basic command handler, bugfixes

This commit is contained in:
Chris 2024-02-27 02:22:49 +01:00
parent c92c40b45a
commit baff64be7a
4 changed files with 70 additions and 5 deletions

21
examples/commands.php Normal file
View File

@ -0,0 +1,21 @@
<?php
use NoccyLabs\React\Shell\CommandHandler;
use React\EventLoop\Loop;
require_once __DIR__."/../vendor/autoload.php";
$shell = new NoccyLabs\React\Shell\Shell();
$commands = new CommandHandler();
$commands->add('help', function ($args, $shell) {
$shell->write("This could be usage help :)\n");
});
$commands->on('notfound', function ($command, $shell) {
$shell->write("Command not found: {$command}. Try help\n");
});
$shell->on('prompt', function ($shell) {
$shell->setPrompt(date(">> "));
});
$shell->on('input', $commands);

View File

@ -2,11 +2,11 @@
use React\EventLoop\Loop; use React\EventLoop\Loop;
require_once __DIR__."/vendor/autoload.php"; require_once __DIR__."/../vendor/autoload.php";
$shell = new NoccyLabs\React\Shell\Shell(); $shell = new NoccyLabs\React\Shell\Shell();
$shell->on('prompt', function () use ($shell) { $shell->on('prompt', function ($shell) {
$shell->setPrompt(date("H:i:s> ")); $shell->setPrompt(date("H:i:s> "));
}); });
$shell->on('input', function (array $input) use ($shell) { $shell->on('input', function (array $input) use ($shell) {

39
src/CommandHandler.php Normal file
View File

@ -0,0 +1,39 @@
<?php
namespace NoccyLabs\React\Shell;
use Evenement\EventEmitterInterface;
use Evenement\EventEmitterTrait;
use React\EventLoop\Loop;
class CommandHandler implements EventEmitterInterface
{
use EventEmitterTrait;
private array $commands = [];
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 (!array_key_exists($command, $this->commands)) {
$this->emit("notfound", [ $command, $shell ]);
return;
}
Loop::futureTick(fn() => call_user_func($this->commands[$command]['handler'], $line, $shell));
}
}

View File

@ -68,11 +68,16 @@ class Shell implements WritableStreamInterface, EventEmitterInterface
exit(0); exit(0);
case "\n": case "\n":
$buffer = str_getcsv($this->buffer, " "); $buffer = str_getcsv(trim($this->buffer), " ");
$this->buffer = ''; $this->buffer = '';
$this->cursorPos = 0; $this->cursorPos = 0;
$this->scrollOffset = 0; $this->scrollOffset = 0;
$this->emit('input', [ $buffer ]); $this->ostream->write("\n");
if ($buffer[0] !== NULL) {
$this->emit('input', [ $buffer, $this ]);
} else {
$this->redrawPrompt();
}
break; break;
case "\x7F": // backspace case "\x7F": // backspace
@ -156,7 +161,7 @@ class Shell implements WritableStreamInterface, EventEmitterInterface
public function redrawPrompt(): void public function redrawPrompt(): void
{ {
$prompt = $this->emit("prompt"); $this->emit("prompt", [ $this ]);
$this->termWidth = intval(exec("tput cols")); $this->termWidth = intval(exec("tput cols"));
$this->isPrompting = true; $this->isPrompting = true;