diff --git a/src/CommandHandler.php b/src/CommandHandler.php index 789065b..73da3b1 100644 --- a/src/CommandHandler.php +++ b/src/CommandHandler.php @@ -35,7 +35,7 @@ class CommandHandler implements EventEmitterInterface array_keys($this->commands), fn($c)=>str_starts_with($c,$command) ); - if (count($candidates)>2) { + if (count($candidates)>1) { $this->emit("candidates", [ $candidates, $shell ]); return; } diff --git a/src/Shell.php b/src/Shell.php index a93a22b..82161f5 100644 --- a/src/Shell.php +++ b/src/Shell.php @@ -35,9 +35,17 @@ class Shell implements WritableStreamInterface, EventEmitterInterface private int $promptWidth = 0; - private string $promptStyle = "36;1"; + private ?string $promptStyle = "36;1"; - private string $inputStyle = "36"; + private ?string $inputStyle = "36"; + + private array $history = []; + + private ?int $historyIndex = null; + + private ?string $historyCache = null; + + private int $maxHistory = 100; public function __construct(?ReadableStreamInterface $input=null, ?WritableStreamInterface $output=null) { @@ -73,6 +81,10 @@ class Shell implements WritableStreamInterface, EventEmitterInterface exit(0); case "\n": + // Update the history + array_unshift($this->history, $this->buffer); + while (count($this->history) > $this->maxHistory) array_pop($this->history); + // Parse and empty the buffer $buffer = str_getcsv(trim($this->buffer), " "); $this->buffer = ''; $this->cursorPos = 0; @@ -98,7 +110,26 @@ class Shell implements WritableStreamInterface, EventEmitterInterface break; case "\e[A": // up + if ($this->historyIndex === null && count($this->history) > 0) { + $this->historyCache = $this->buffer; + $this->historyIndex = 0; + $this->buffer = $this->history[$this->historyIndex]; + } elseif ($this->historyIndex < count($this->history) - 1) { + $this->historyIndex++; + $this->buffer = $this->history[$this->historyIndex]; + } + break; case "\e[B": // down + if ($this->historyIndex === null) { + break; + } elseif ($this->historyIndex === 0) { + $this->historyIndex = null; + $this->buffer = $this->historyCache; + $this->historyCache = null; + } else { + $this->historyIndex--; + $this->buffer = $this->history[$this->historyIndex]; + } break; case "\e[H": // home