Improvements
This commit is contained in:
parent
e6f6fbe3d3
commit
0c64bc2f70
@ -1,46 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once __DIR__."/../vendor/autoload.php";
|
|
||||||
|
|
||||||
use NoccyLabs\Shell\Shell;
|
|
||||||
|
|
||||||
class MyShell extends Shell
|
|
||||||
{
|
|
||||||
|
|
||||||
protected $params;
|
|
||||||
|
|
||||||
protected function setParam($key, $value=null)
|
|
||||||
{
|
|
||||||
$this->params[$key] = $value;
|
|
||||||
$this->writeln(" ** {$key} = {$value}");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function configure(array $config)
|
|
||||||
{
|
|
||||||
$this->addCommand("set", [$this,"setParam"]);
|
|
||||||
$this->addCommand("exit", [$this,"stop"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getPrompt()
|
|
||||||
{
|
|
||||||
return "flinger: ";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function onUpdate()
|
|
||||||
{
|
|
||||||
static $lt;
|
|
||||||
$t = floor(microtime(true));
|
|
||||||
if ($t > $lt) {
|
|
||||||
$lt = $t + 5;
|
|
||||||
echo date("Y-m-d h:i:s")."\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function onInput($buffer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
$myShell = new MyShell();
|
|
||||||
$myShell->run();
|
|
58
examples/simple.php
Normal file
58
examples/simple.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__."/../vendor/autoload.php";
|
||||||
|
|
||||||
|
use NoccyLabs\Shell\Shell;
|
||||||
|
use NoccyLabs\Shell\Command;
|
||||||
|
|
||||||
|
class MyCommand extends Command
|
||||||
|
{
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return "mycommand";
|
||||||
|
}
|
||||||
|
public function execute()
|
||||||
|
{
|
||||||
|
$this->writeln("Executing command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyShell extends Shell
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $seq = 0;
|
||||||
|
|
||||||
|
protected function configure(array $config)
|
||||||
|
{
|
||||||
|
$this->addCommand("hello", function () {
|
||||||
|
echo "world\n\rthis\n\ris\n\ra\ntest\n\r";
|
||||||
|
});
|
||||||
|
$this->addCommand(new MyCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPrompt()
|
||||||
|
{
|
||||||
|
return "test[{$this->seq}]: ";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function onUpdate()
|
||||||
|
{
|
||||||
|
static $lt;
|
||||||
|
$t = floor(microtime(true));
|
||||||
|
if ($t > $lt) {
|
||||||
|
$lt = $t + 5;
|
||||||
|
echo date("Y-m-d h:i:s")."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function onCommand($buffer)
|
||||||
|
{
|
||||||
|
$this->seq++;
|
||||||
|
parent::onCommand($buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$myShell = new MyShell();
|
||||||
|
$myShell->run();
|
||||||
|
echo "Exiting\n";
|
38
lib/Command.php
Normal file
38
lib/Command.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace NoccyLabs\Shell;
|
||||||
|
|
||||||
|
use NoccyLabs\Shell\LineRead;
|
||||||
|
|
||||||
|
abstract class Command
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $name;
|
||||||
|
|
||||||
|
protected $deescription;
|
||||||
|
|
||||||
|
protected $shell;
|
||||||
|
|
||||||
|
public function setShell(Shell $shell)
|
||||||
|
{
|
||||||
|
$this->shell = $shell;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function writeln($str)
|
||||||
|
{
|
||||||
|
$this->shell->writeln($str);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function getName();
|
||||||
|
|
||||||
|
public function getDescription()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public function getHelp()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public function run(array $args)
|
||||||
|
{
|
||||||
|
call_user_func_array([$this,"execute"], $args);
|
||||||
|
}
|
||||||
|
}
|
@ -29,13 +29,13 @@ class LineRead
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
stream_set_blocking(STDIN, false);
|
stream_set_blocking(STDIN, false);
|
||||||
$this->sttyOld = exec('stty -g');
|
$this->sttyOld = trim(exec('stty -g'));
|
||||||
exec('stty raw -echo isig');
|
exec('stty raw -echo'); // isig');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
exec('stty {$this->sttyOld}');
|
exec('stty '.$this->sttyOld);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update()
|
public function update()
|
||||||
@ -57,8 +57,8 @@ class LineRead
|
|||||||
{
|
{
|
||||||
$prompt = $this->prompt;
|
$prompt = $this->prompt;
|
||||||
$buffer = $this->buffer;
|
$buffer = $this->buffer;
|
||||||
$cursor = strlen($this->prompt) + 2 + $this->posCursor - $this->posScroll;
|
$cursor = strlen($this->prompt) + 1 + $this->posCursor - $this->posScroll;
|
||||||
fprintf(STDOUT, "\r\e[2K\e[36;1;4m%s\e[37;24m %s\e[%dG\e[0m", $prompt, $buffer, $cursor);
|
fprintf(STDOUT, "\r\e[2K\e[32;1m%s\e[37m%s\e[%dG\e[0m", $prompt, $buffer, $cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function handleInput()
|
protected function handleInput()
|
||||||
@ -75,6 +75,11 @@ class LineRead
|
|||||||
$keyBuffer = substr($keyBuffer, 3);
|
$keyBuffer = substr($keyBuffer, 3);
|
||||||
$this->parseControlCode($ctrlChar);
|
$this->parseControlCode($ctrlChar);
|
||||||
}
|
}
|
||||||
|
} elseif ($keyBuffer[0]=="\x03") {
|
||||||
|
$this->posCursor = 0;
|
||||||
|
$this->buffer = null;
|
||||||
|
fprintf(STDOUT, "\r\n");
|
||||||
|
return $keyBuffer[0];
|
||||||
} else {
|
} else {
|
||||||
$keyChar = $keyBuffer[0];
|
$keyChar = $keyBuffer[0];
|
||||||
$keyCode = ord($keyChar);
|
$keyCode = ord($keyChar);
|
||||||
@ -95,7 +100,7 @@ class LineRead
|
|||||||
$returnBuffer = $this->buffer;
|
$returnBuffer = $this->buffer;
|
||||||
$this->buffer = null;
|
$this->buffer = null;
|
||||||
$this->posCursor = 0;
|
$this->posCursor = 0;
|
||||||
printf("\n");
|
printf("\n\r");
|
||||||
$this->state = self::STATE_IDLE;
|
$this->state = self::STATE_IDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,4 +138,9 @@ class LineRead
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setPrompt($prompt)
|
||||||
|
{
|
||||||
|
$this->prompt = $prompt;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,26 +13,50 @@ abstract class Shell
|
|||||||
|
|
||||||
abstract protected function configure(array $config);
|
abstract protected function configure(array $config);
|
||||||
|
|
||||||
public function addCommand($command, callable $handler)
|
public function addCommand($command, callable $handler=null)
|
||||||
{
|
{
|
||||||
|
if (!$handler) {
|
||||||
|
if (!($command instanceof Command)) {
|
||||||
|
throw new \RuntimeException("Handler is not callable nor a Command");
|
||||||
|
}
|
||||||
|
$command->setShell($this);
|
||||||
|
$this->commands[$command->getName()] = $command;
|
||||||
|
} else {
|
||||||
$this->commands[$command] = $handler;
|
$this->commands[$command] = $handler;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function execute($command)
|
public function execute($command)
|
||||||
{
|
{
|
||||||
|
if (is_array($command)) {
|
||||||
|
foreach ($command as $cmd) {
|
||||||
|
$this->execute($cmd);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$buffer = str_getcsv($command, " ", "\"", "\\");
|
$buffer = str_getcsv($command, " ", "\"", "\\");
|
||||||
|
|
||||||
if (count($buffer)>0) {
|
if (count($buffer)>0) {
|
||||||
$this->executeBuffer($buffer);
|
$this->onCommand($buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function onCommand($buffer)
|
||||||
|
{
|
||||||
|
$this->executeBuffer($buffer);
|
||||||
|
}
|
||||||
|
|
||||||
protected function executeBuffer(array $buffer)
|
protected function executeBuffer(array $buffer)
|
||||||
{
|
{
|
||||||
$commandName = array_shift($buffer);
|
$commandName = array_shift($buffer);
|
||||||
if (array_key_exists($commandName, $this->commands)) {
|
if (array_key_exists($commandName, $this->commands)) {
|
||||||
$command = $this->commands[$commandName];
|
$command = $this->commands[$commandName];
|
||||||
|
if ($command instanceof Command) {
|
||||||
|
$command->run($buffer);
|
||||||
|
} else {
|
||||||
call_user_func_array($command,$buffer);
|
call_user_func_array($command,$buffer);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->writeln("Bad command: ".$commandName);
|
$this->writeln("Bad command: ".$commandName);
|
||||||
@ -47,35 +71,32 @@ abstract class Shell
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run(callable $updateFunc=null)
|
public function run()
|
||||||
{
|
{
|
||||||
$lineRead = new LineRead();
|
$lineRead = new LineRead();
|
||||||
|
|
||||||
$this->running = true;
|
$this->running = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
$lineRead->setPrompt($this->getPrompt());
|
||||||
$buffer = $lineRead->update();
|
$buffer = $lineRead->update();
|
||||||
ob_start();
|
if ($buffer == "\x03") {
|
||||||
if (is_callable($updateFunc)) {
|
$this->stop();
|
||||||
call_user_func($updateFunc);
|
continue;
|
||||||
}
|
}
|
||||||
|
ob_start();
|
||||||
$this->onUpdate();
|
$this->onUpdate();
|
||||||
|
if ($buffer !== null) {
|
||||||
|
$this->execute($buffer);
|
||||||
|
}
|
||||||
$buf = ob_get_contents();
|
$buf = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
if ($buf) {
|
if ($buf) {
|
||||||
$lineRead->erase();
|
$lineRead->erase();
|
||||||
echo rtrim($buf)."\n";
|
echo str_replace("\n", "\r\n", rtrim($buf)."\n");
|
||||||
$lineRead->redraw();
|
$lineRead->redraw();
|
||||||
}
|
}
|
||||||
//$buffer = readline($this->getPrompt());
|
|
||||||
if ($buffer === null) {
|
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
$this->execute($buffer);
|
|
||||||
}
|
|
||||||
} while ($this->running);
|
} while ($this->running);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user