Basic history support with up/down arrow keys

This commit is contained in:
Chris 2024-02-28 12:34:47 +01:00
parent ba27d840ea
commit 6eddf0e847
2 changed files with 34 additions and 3 deletions

View File

@ -35,7 +35,7 @@ class CommandHandler implements EventEmitterInterface
array_keys($this->commands), array_keys($this->commands),
fn($c)=>str_starts_with($c,$command) fn($c)=>str_starts_with($c,$command)
); );
if (count($candidates)>2) { if (count($candidates)>1) {
$this->emit("candidates", [ $candidates, $shell ]); $this->emit("candidates", [ $candidates, $shell ]);
return; return;
} }

View File

@ -35,9 +35,17 @@ class Shell implements WritableStreamInterface, EventEmitterInterface
private int $promptWidth = 0; 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) public function __construct(?ReadableStreamInterface $input=null, ?WritableStreamInterface $output=null)
{ {
@ -73,6 +81,10 @@ class Shell implements WritableStreamInterface, EventEmitterInterface
exit(0); exit(0);
case "\n": 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), " "); $buffer = str_getcsv(trim($this->buffer), " ");
$this->buffer = ''; $this->buffer = '';
$this->cursorPos = 0; $this->cursorPos = 0;
@ -98,7 +110,26 @@ class Shell implements WritableStreamInterface, EventEmitterInterface
break; break;
case "\e[A": // up 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 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; break;
case "\e[H": // home case "\e[H": // home