Clean up key mapping with more constants

This commit is contained in:
Timothy Warren 2020-01-27 15:11:20 -05:00
parent 24baca3cb8
commit 54bc83e1f9
5 changed files with 102 additions and 65 deletions

View File

@ -103,6 +103,13 @@ class ANSI {
return self::seq('%dT', $lines); return self::seq('%dT', $lines);
} }
/**
* Simplify creating ansi escape codes
*
* @param string $pattern
* @param mixed ...$args
* @return string
*/
private static function seq(string $pattern, ...$args): string private static function seq(string $pattern, ...$args): string
{ {
return sprintf("\e[{$pattern}", ...$args); return sprintf("\e[{$pattern}", ...$args);

View File

@ -2,11 +2,7 @@
namespace Aviat\Kilo; namespace Aviat\Kilo;
use Aviat\Kilo\Enum\{ use Aviat\Kilo\Enum\{Color, KeyCode, KeyType, Highlight};
Color,
Key,
Highlight,
};
use Aviat\Kilo\Tokens\PHP; use Aviat\Kilo\Tokens\PHP;
/** /**
@ -92,40 +88,42 @@ class Editor {
{ {
$c = read_stdin(); $c = read_stdin();
// @TODO Make this more DRY $simpleMap = [
switch ($c) KeyCode::ARROW_DOWN => KeyType::ARROW_DOWN,
KeyCode::ARROW_LEFT => KeyType::ARROW_LEFT,
KeyCode::ARROW_RIGHT => KeyType::ARROW_RIGHT,
KeyCode::ARROW_UP => KeyType::ARROW_UP,
KeyCode::BACKSPACE => KeyType::BACKSPACE,
KeyCode::DEL_KEY => KeyType::DEL_KEY,
KeyCode::ENTER => KeyType::ENTER,
KeyCode::ESCAPE => KeyType::ESCAPE,
KeyCode::PAGE_DOWN => KeyType::PAGE_DOWN,
KeyCode::PAGE_UP => KeyType::PAGE_UP,
];
$multiMap = [
"\eOH" => KeyType::HOME_KEY,
"\e[1~" => KeyType::HOME_KEY,
"\e[7~" => KeyType::HOME_KEY,
ANSI::RESET_CURSOR => KeyType::HOME_KEY,
"\eOF" => KeyType::END_KEY,
"\e[4~" => KeyType::END_KEY,
"\e[8~" => KeyType::END_KEY,
"\e[F" => KeyType::END_KEY,
];
if (array_key_exists($c, $simpleMap))
{ {
case "\x7f": return Key::BACKSPACE; return $simpleMap[$c];
case "\r": return Key::ENTER;
case "\e[A": return Key::ARROW_UP;
case "\e[B": return Key::ARROW_DOWN;
case "\e[C": return Key::ARROW_RIGHT;
case "\e[D": return Key::ARROW_LEFT;
case "\e[3~": return Key::DEL_KEY;
case "\e[5~": return Key::PAGE_UP;
case "\e[6~": return Key::PAGE_DOWN;
case "\eOH":
case "\e[1~":
case "\e[7~":
case ANSI::RESET_CURSOR:
return Key::HOME_KEY;
case "\eOF":
case "\e[4~":
case "\e[8~":
case "\e[F":
return Key::END_KEY;
case "\e":
return Key::ESCAPE;
default: return $c;
} }
if (array_key_exists($c, $multiMap))
{
return $multiMap[$c];
}
return $c;
} }
protected function selectSyntaxHighlight(): void protected function selectSyntaxHighlight(): void
@ -435,11 +433,11 @@ class Editor {
return; return;
} }
if ($key === Key::ARROW_RIGHT || $key === Key::ARROW_DOWN) if ($key === KeyType::ARROW_RIGHT || $key === KeyType::ARROW_DOWN)
{ {
$direction = 1; $direction = 1;
} }
else if ($key === Key::ARROW_LEFT || $key === Key::ARROW_UP) else if ($key === KeyType::ARROW_LEFT || $key === KeyType::ARROW_UP)
{ {
$direction = -1; $direction = -1;
} }
@ -730,7 +728,7 @@ class Editor {
protected function prompt(string $prompt, ?callable $callback = NULL): string protected function prompt(string $prompt, ?callable $callback = NULL): string
{ {
$buffer = ''; $buffer = '';
$modifiers = Key::getConstList(); $modifiers = KeyType::getConstList();
while (TRUE) while (TRUE)
{ {
$this->setStatusMessage($prompt, $buffer); $this->setStatusMessage($prompt, $buffer);
@ -738,7 +736,7 @@ class Editor {
$c = $this->readKey(); $c = $this->readKey();
if ($c === Key::ESCAPE) if ($c === KeyType::ESCAPE)
{ {
$this->setStatusMessage(''); $this->setStatusMessage('');
if ($callback !== NULL) if ($callback !== NULL)
@ -748,7 +746,7 @@ class Editor {
return ''; return '';
} }
if ($c === Key::ENTER && $buffer !== '') if ($c === KeyType::ENTER && $buffer !== '')
{ {
$this->setStatusMessage(''); $this->setStatusMessage('');
if ($callback !== NULL) if ($callback !== NULL)
@ -758,7 +756,7 @@ class Editor {
return $buffer; return $buffer;
} }
if ($c === Key::DEL_KEY || $c === Key::BACKSPACE || $c === chr(ctrl_key('h'))) if ($c === KeyType::DEL_KEY || $c === KeyType::BACKSPACE || $c === chr(ctrl_key('h')))
{ {
$buffer = substr($buffer, 0, -1); $buffer = substr($buffer, 0, -1);
} }
@ -782,7 +780,7 @@ class Editor {
switch ($key) switch ($key)
{ {
case Key::ARROW_LEFT: case KeyType::ARROW_LEFT:
if ($this->cursorX !== 0) if ($this->cursorX !== 0)
{ {
$this->cursorX--; $this->cursorX--;
@ -794,7 +792,7 @@ class Editor {
} }
break; break;
case Key::ARROW_RIGHT: case KeyType::ARROW_RIGHT:
if ($row && $this->cursorX < $row->size) if ($row && $this->cursorX < $row->size)
{ {
$this->cursorX++; $this->cursorX++;
@ -806,14 +804,14 @@ class Editor {
} }
break; break;
case Key::ARROW_UP: case KeyType::ARROW_UP:
if ($this->cursorY !== 0) if ($this->cursorY !== 0)
{ {
$this->cursorY--; $this->cursorY--;
} }
break; break;
case Key::ARROW_DOWN: case KeyType::ARROW_DOWN:
if ($this->cursorY < $this->numRows) if ($this->cursorY < $this->numRows)
{ {
$this->cursorY++; $this->cursorY++;
@ -844,7 +842,7 @@ class Editor {
switch ($c) switch ($c)
{ {
case Key::ENTER: case KeyType::ENTER:
$this->insertNewline(); $this->insertNewline();
break; break;
@ -865,11 +863,11 @@ class Editor {
$this->save(); $this->save();
break; break;
case Key::HOME_KEY: case KeyType::HOME_KEY:
$this->cursorX = 0; $this->cursorX = 0;
break; break;
case Key::END_KEY: case KeyType::END_KEY:
if ($this->cursorY < $this->numRows) if ($this->cursorY < $this->numRows)
{ {
$this->cursorX = $this->rows[$this->cursorY]->size - 1; $this->cursorX = $this->rows[$this->cursorY]->size - 1;
@ -880,30 +878,30 @@ class Editor {
$this->find(); $this->find();
break; break;
case Key::BACKSPACE: case KeyType::BACKSPACE:
case chr(ctrl_key('h')): case chr(ctrl_key('h')):
case Key::DEL_KEY: case KeyType::DEL_KEY:
if ($c === Key::DEL_KEY) if ($c === KeyType::DEL_KEY)
{ {
$this->moveCursor(Key::ARROW_RIGHT); $this->moveCursor(KeyType::ARROW_RIGHT);
} }
$this->deleteChar(); $this->deleteChar();
break; break;
case Key::PAGE_UP: case KeyType::PAGE_UP:
case Key::PAGE_DOWN: case KeyType::PAGE_DOWN:
$this->pageUpOrDown($c); $this->pageUpOrDown($c);
break; break;
case Key::ARROW_UP: case KeyType::ARROW_UP:
case Key::ARROW_DOWN: case KeyType::ARROW_DOWN:
case Key::ARROW_LEFT: case KeyType::ARROW_LEFT:
case Key::ARROW_RIGHT: case KeyType::ARROW_RIGHT:
$this->moveCursor($c); $this->moveCursor($c);
break; break;
case chr(ctrl_key('l')): case chr(ctrl_key('l')):
case Key::ESCAPE: case KeyType::ESCAPE:
// Do nothing // Do nothing
break; break;
@ -919,11 +917,11 @@ class Editor {
private function pageUpOrDown(string $c): void private function pageUpOrDown(string $c): void
{ {
if ($c === Key::PAGE_UP) if ($c === KeyType::PAGE_UP)
{ {
$this->cursorY = $this->rowOffset; $this->cursorY = $this->rowOffset;
} }
else if ($c === Key::PAGE_DOWN) else if ($c === KeyType::PAGE_DOWN)
{ {
$this->cursorY = $this->rowOffset + $this->screenRows - 1; $this->cursorY = $this->rowOffset + $this->screenRows - 1;
if ($this->cursorY > $this->numRows) if ($this->cursorY > $this->numRows)
@ -935,7 +933,7 @@ class Editor {
$times = $this->screenRows; $times = $this->screenRows;
for (; $times > 0; $times--) for (; $times > 0; $times--)
{ {
$this->moveCursor($c === Key::PAGE_UP ? Key::ARROW_UP : Key::ARROW_DOWN); $this->moveCursor($c === KeyType::PAGE_UP ? KeyType::ARROW_UP : KeyType::ARROW_DOWN);
} }
} }

12
src/Enum/Event.php Normal file
View File

@ -0,0 +1,12 @@
<?php declare(strict_types=1);
namespace Aviat\Kilo\Enum;
use Aviat\Kilo\Traits;
class Event {
use Traits\ConstList;
public const INPUT_KEY = 'INPUT_KEY';
public const QUIT_ATTEMPT = 'QUIT_ATTEMPT';
}

20
src/Enum/KeyCode.php Normal file
View File

@ -0,0 +1,20 @@
<?php declare(strict_types=1);
namespace Aviat\Kilo\Enum;
use Aviat\Kilo\Traits;
class KeyCode {
use Traits\ConstList;
public const ARROW_DOWN = "\e[B";
public const ARROW_LEFT = "\e[D";
public const ARROW_RIGHT = "\e[C";
public const ARROW_UP = "\e[A";
public const BACKSPACE = "\x7f";
public const DEL_KEY = "\e[3~";
public const ENTER = "\r";
public const ESCAPE = "\e";
public const PAGE_DOWN = "\e[6~";
public const PAGE_UP = "\e[5~";
}

View File

@ -4,7 +4,7 @@ namespace Aviat\Kilo\Enum;
use Aviat\Kilo\Traits; use Aviat\Kilo\Traits;
class Key { class KeyType {
use Traits\ConstList; use Traits\ConstList;
public const ARROW_DOWN = 'ARROW_DOWN'; public const ARROW_DOWN = 'ARROW_DOWN';