Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
75c624520d | |||
ec60970b5d | |||
7c76928c3b | |||
ff9845e23e | |||
e5b328b822 | |||
cee82fc740 | |||
c7b1a637c2 |
@ -16,10 +16,6 @@ Major changes:
|
|||||||
* The event `Shell::EVT_BAD_COMMAND` will be fired if a command can
|
* The event `Shell::EVT_BAD_COMMAND` will be fired if a command can
|
||||||
not be found, assuming `Context->execute()` does not accept the
|
not be found, assuming `Context->execute()` does not accept the
|
||||||
command. (see *examples/commandevents.php*)
|
command. (see *examples/commandevents.php*)
|
||||||
* When calling `Context->addCommand()` you can now use both `help`
|
|
||||||
and `descr` as the last argument to provide the description text
|
|
||||||
for the command. This change is intended to make `addCommand` and
|
|
||||||
the doccomment `@descr` more similar.
|
|
||||||
|
|
||||||
New features:
|
New features:
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ $myShell->setPrompt("test>");
|
|||||||
$ctx = $myShell->createContext("root");
|
$ctx = $myShell->createContext("root");
|
||||||
$ctx->addCommand("hello", function () {
|
$ctx->addCommand("hello", function () {
|
||||||
echo "Hello World!\n";
|
echo "Hello World!\n";
|
||||||
}, [ 'descr'=>'Say hello' ]);
|
}, [ 'help'=>'Say hello' ]);
|
||||||
|
|
||||||
// Run the shell
|
// Run the shell
|
||||||
$myShell->run();
|
$myShell->run();
|
||||||
|
@ -36,9 +36,9 @@ $myShell->setPrompt("test>");
|
|||||||
|
|
||||||
// Create an anonymous context and add a command
|
// Create an anonymous context and add a command
|
||||||
$ctx = $myShell->createContext("root");
|
$ctx = $myShell->createContext("root");
|
||||||
$ctx->addCommand("hello", function () {
|
$ctx->addCommand("hello", function ($who="World") {
|
||||||
echo "Hello World!\n";
|
echo "Hello {$who}!\n";
|
||||||
});
|
}, [ "help"=>"Say hello", "args"=>"who" ]);
|
||||||
|
|
||||||
// Run the shell
|
// Run the shell
|
||||||
$myShell->run();
|
$myShell->run();
|
||||||
|
@ -6,21 +6,46 @@ use NoccyLabs\Shell\Shell;
|
|||||||
use NoccyLabs\Shell\Context;
|
use NoccyLabs\Shell\Context;
|
||||||
|
|
||||||
$shell = new Shell();
|
$shell = new Shell();
|
||||||
$shell->addListener("prompt", function ($event, $shell) {
|
$shell->addListener(Shell::EVT_UPDATE_PROMPT, function ($event) {
|
||||||
$name = $shell->getContextPath();
|
$name = $event->shell->getContextPath();
|
||||||
$shell->setPrompt("shell{$name}> ");
|
$event->shell->setPrompt("shell{$name}> ");
|
||||||
});
|
});
|
||||||
|
|
||||||
$root = new Context();
|
class MyContext extends Context
|
||||||
$root->addCommand("test", function () {
|
{
|
||||||
echo "It works!\n";
|
public function __construct()
|
||||||
});
|
{
|
||||||
$root->addCommand("context", function ($name) {
|
// Remember to call the parent constructor if you want to use
|
||||||
$context = new Context($name);
|
// the doccomment syntax to mark commands, as demonstrated
|
||||||
$context->name = $name;
|
// at the end of this class for the bar command.
|
||||||
return $context;
|
parent::__construct();
|
||||||
});
|
$this->addCommand("foo",[$this,"foo"],[
|
||||||
$shell->pushContext($root);
|
'help' => "Foo command"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onEnter()
|
||||||
|
{
|
||||||
|
echo "Entering context!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function foo()
|
||||||
|
{
|
||||||
|
echo "Foo!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @command bar
|
||||||
|
* @args
|
||||||
|
* @help Bar command
|
||||||
|
*/
|
||||||
|
public function bar()
|
||||||
|
{
|
||||||
|
echo "Bar!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$shell->pushContext(new MyContext());
|
||||||
|
|
||||||
|
|
||||||
$shell->run();
|
$shell->run();
|
||||||
|
31
examples/input.php
Normal file
31
examples/input.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This example demonstrates how to use events to catch commands that
|
||||||
|
* have not been handled by any context or builtin.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once __DIR__."/../vendor/autoload.php";
|
||||||
|
|
||||||
|
use NoccyLabs\Shell\Shell;
|
||||||
|
use NoccyLabs\Shell\Style;
|
||||||
|
use NoccyLabs\Shell\Context;
|
||||||
|
|
||||||
|
$myShell = new Shell();
|
||||||
|
|
||||||
|
// Set the initial prompt, not really needed.
|
||||||
|
$myShell->setPrompt("test>");
|
||||||
|
|
||||||
|
// Create an anonymous context and add a command
|
||||||
|
$ctx = $myShell->createContext("root");
|
||||||
|
$ctx->addCommand("hello", function () use ($myShell) {
|
||||||
|
$myShell->getInput("What is your name?", function ($name) use ($myShell) {
|
||||||
|
echo "Hello, {$name}\n";
|
||||||
|
$myShell->getInput("Who is your daddy and what does he do?", function ($daddy) {
|
||||||
|
echo "{$daddy}? Oookay...\n";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run the shell
|
||||||
|
$myShell->run();
|
@ -66,6 +66,11 @@ class Context
|
|||||||
$this->findCommands();
|
$this->findCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onEnter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected function findCommands()
|
protected function findCommands()
|
||||||
{
|
{
|
||||||
$refl = new \ReflectionClass(get_called_class());
|
$refl = new \ReflectionClass(get_called_class());
|
||||||
@ -132,7 +137,6 @@ class Context
|
|||||||
$info = $this->commandInfo[$command];
|
$info = $this->commandInfo[$command];
|
||||||
$args = array_key_exists("args",$info)?$info['args']:"";
|
$args = array_key_exists("args",$info)?$info['args']:"";
|
||||||
$help = array_key_exists("help",$info)?$info['help']:"";
|
$help = array_key_exists("help",$info)?$info['help']:"";
|
||||||
$help = $help?:(array_key_exists("descr",$info)?$info['descr']:"");
|
|
||||||
$ret[trim("{$command} {$args}")] = $help;
|
$ret[trim("{$command} {$args}")] = $help;
|
||||||
}
|
}
|
||||||
return $ret;
|
return $ret;
|
||||||
|
@ -54,6 +54,18 @@ class Shell
|
|||||||
* @var Style The style applied to the input text
|
* @var Style The style applied to the input text
|
||||||
*/
|
*/
|
||||||
protected $input_style = null;
|
protected $input_style = null;
|
||||||
|
/**
|
||||||
|
* @var callable The callback to pass the input on to
|
||||||
|
*/
|
||||||
|
protected $input_callback = null;
|
||||||
|
/**
|
||||||
|
* @var string Question prompt for getInput()
|
||||||
|
*/
|
||||||
|
protected $input_prompt = null;
|
||||||
|
/**
|
||||||
|
* @var string The prompt before changing to $input_prompt
|
||||||
|
*/
|
||||||
|
protected $input_last_prompt = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@ -78,6 +90,16 @@ class Shell
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current context
|
||||||
|
*
|
||||||
|
* @return Context The current context
|
||||||
|
*/
|
||||||
|
public function getContext()
|
||||||
|
{
|
||||||
|
return $this->context;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Push a new primary context, saving the previous contexts on a stack.
|
* Push a new primary context, saving the previous contexts on a stack.
|
||||||
*
|
*
|
||||||
@ -91,6 +113,7 @@ class Shell
|
|||||||
}
|
}
|
||||||
$context->setShell($this);
|
$context->setShell($this);
|
||||||
$this->context = $context;
|
$this->context = $context;
|
||||||
|
$context->onEnter();
|
||||||
$this->dispatchEvent(self::EVT_CONTEXT_CHANGED);
|
$this->dispatchEvent(self::EVT_CONTEXT_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,19 +418,27 @@ class Shell
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ksort($ghelp);
|
ksort($ghelp);
|
||||||
printf("Commands in current context:\n");
|
$_ = function($command,$args,$info) {
|
||||||
|
printf(" \e[96m%s\e[0m \e[0;3m%s\e[0m \e[30G\e[36m%s\e[0m\n", $command, $args, $info);
|
||||||
|
};
|
||||||
|
printf("\e[1mCommands:\e[0m\n");
|
||||||
foreach ($help as $command=>$info) {
|
foreach ($help as $command=>$info) {
|
||||||
printf(" %-20s %s\n", $command, $info);
|
if (strpos($command," ")!==false) {
|
||||||
|
list($command,$args) = explode(" ",$command,2);
|
||||||
|
} else $args=null;
|
||||||
|
$_($command, $args,$info);
|
||||||
}
|
}
|
||||||
if (count($ghelp)) {
|
if (count($ghelp)) {
|
||||||
printf("\nImported from parent contexts:\n");
|
printf("\e[1mCommands from parent contexts:\e[0m\n");
|
||||||
foreach ($ghelp as $command=>$info) {
|
if (strpos($command," ")!==false) {
|
||||||
printf(" %-20s %s\n", $command, $info);
|
list($command,$args) = explode(" ",$command,2);
|
||||||
|
} else $args=null;
|
||||||
|
$_($command, $args,$info);
|
||||||
}
|
}
|
||||||
}
|
printf("\e[1mGlobal commands:\e[0m\n");
|
||||||
printf("\nGlobal commands:\n");
|
$_("exit", null, "Leave the shell");
|
||||||
printf(" %-20s %s\n", "exit", "Leave the shell");
|
$_(".", null, "Show the context tree");
|
||||||
printf(" %-20s %s\n", "..", "Discard the current context and go to parent");
|
$_("..", null, "Discard the current context and go to parent");
|
||||||
break;
|
break;
|
||||||
case 'exit':
|
case 'exit':
|
||||||
$this->stop();
|
$this->stop();
|
||||||
@ -532,6 +563,31 @@ class Shell
|
|||||||
return $event;
|
return $event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getInput($prompt, callable $callback)
|
||||||
|
{
|
||||||
|
$this->addListener(Shell::EVT_UPDATE_PROMPT, [ $this, "onInputPrompt" ], $prompt);
|
||||||
|
$this->addListener(Shell::EVT_BEFORE_COMMAND, [ $this, "onInputHandler" ], $this->prompt, $callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onInputPrompt(Event $e, $prompt)
|
||||||
|
{
|
||||||
|
$this->setPrompt($prompt);
|
||||||
|
$e->stopPropagation();
|
||||||
|
$this->removeListener(Shell::EVT_UPDATE_PROMPT, [ $this, "onInputPrompt" ], $prompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onInputHandler(Event $e, $last_prompt, $callback)
|
||||||
|
{
|
||||||
|
// Restore the prompt
|
||||||
|
$this->setPrompt($last_prompt);
|
||||||
|
// Remove the listeners and compose the result string
|
||||||
|
$this->removeListener(Shell::EVT_BEFORE_COMMAND, [ $this, "onInputHandler" ], $last_prompt, $callback);
|
||||||
|
$input = trim($e->command." ".join(" ",$e->args));
|
||||||
|
$e->stopPropagation();
|
||||||
|
// Call the callback
|
||||||
|
call_user_func($callback, $input);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop the shell; calling this method will cause the main run() to return.
|
* Stop the shell; calling this method will cause the main run() to return.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user