diff --git a/src/ANSI.php b/src/ANSI.php index e337411..8091cd9 100644 --- a/src/ANSI.php +++ b/src/ANSI.php @@ -103,6 +103,13 @@ class ANSI { 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 { return sprintf("\e[{$pattern}", ...$args); diff --git a/src/Editor.php b/src/Editor.php index 065140b..61d67b3 100644 --- a/src/Editor.php +++ b/src/Editor.php @@ -2,11 +2,7 @@ namespace Aviat\Kilo; -use Aviat\Kilo\Enum\{ - Color, - Key, - Highlight, -}; +use Aviat\Kilo\Enum\{Color, KeyCode, KeyType, Highlight}; use Aviat\Kilo\Tokens\PHP; /** @@ -92,40 +88,42 @@ class Editor { { $c = read_stdin(); - // @TODO Make this more DRY - switch ($c) + $simpleMap = [ + 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; - - 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; + return $simpleMap[$c]; } + + if (array_key_exists($c, $multiMap)) + { + return $multiMap[$c]; + } + + return $c; } protected function selectSyntaxHighlight(): void @@ -435,11 +433,11 @@ class Editor { return; } - if ($key === Key::ARROW_RIGHT || $key === Key::ARROW_DOWN) + if ($key === KeyType::ARROW_RIGHT || $key === KeyType::ARROW_DOWN) { $direction = 1; } - else if ($key === Key::ARROW_LEFT || $key === Key::ARROW_UP) + else if ($key === KeyType::ARROW_LEFT || $key === KeyType::ARROW_UP) { $direction = -1; } @@ -730,7 +728,7 @@ class Editor { protected function prompt(string $prompt, ?callable $callback = NULL): string { $buffer = ''; - $modifiers = Key::getConstList(); + $modifiers = KeyType::getConstList(); while (TRUE) { $this->setStatusMessage($prompt, $buffer); @@ -738,7 +736,7 @@ class Editor { $c = $this->readKey(); - if ($c === Key::ESCAPE) + if ($c === KeyType::ESCAPE) { $this->setStatusMessage(''); if ($callback !== NULL) @@ -748,7 +746,7 @@ class Editor { return ''; } - if ($c === Key::ENTER && $buffer !== '') + if ($c === KeyType::ENTER && $buffer !== '') { $this->setStatusMessage(''); if ($callback !== NULL) @@ -758,7 +756,7 @@ class Editor { 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); } @@ -782,7 +780,7 @@ class Editor { switch ($key) { - case Key::ARROW_LEFT: + case KeyType::ARROW_LEFT: if ($this->cursorX !== 0) { $this->cursorX--; @@ -794,7 +792,7 @@ class Editor { } break; - case Key::ARROW_RIGHT: + case KeyType::ARROW_RIGHT: if ($row && $this->cursorX < $row->size) { $this->cursorX++; @@ -806,14 +804,14 @@ class Editor { } break; - case Key::ARROW_UP: + case KeyType::ARROW_UP: if ($this->cursorY !== 0) { $this->cursorY--; } break; - case Key::ARROW_DOWN: + case KeyType::ARROW_DOWN: if ($this->cursorY < $this->numRows) { $this->cursorY++; @@ -844,7 +842,7 @@ class Editor { switch ($c) { - case Key::ENTER: + case KeyType::ENTER: $this->insertNewline(); break; @@ -865,11 +863,11 @@ class Editor { $this->save(); break; - case Key::HOME_KEY: + case KeyType::HOME_KEY: $this->cursorX = 0; break; - case Key::END_KEY: + case KeyType::END_KEY: if ($this->cursorY < $this->numRows) { $this->cursorX = $this->rows[$this->cursorY]->size - 1; @@ -880,30 +878,30 @@ class Editor { $this->find(); break; - case Key::BACKSPACE: + case KeyType::BACKSPACE: case chr(ctrl_key('h')): - case Key::DEL_KEY: - if ($c === Key::DEL_KEY) + case KeyType::DEL_KEY: + if ($c === KeyType::DEL_KEY) { - $this->moveCursor(Key::ARROW_RIGHT); + $this->moveCursor(KeyType::ARROW_RIGHT); } $this->deleteChar(); break; - case Key::PAGE_UP: - case Key::PAGE_DOWN: + case KeyType::PAGE_UP: + case KeyType::PAGE_DOWN: $this->pageUpOrDown($c); break; - case Key::ARROW_UP: - case Key::ARROW_DOWN: - case Key::ARROW_LEFT: - case Key::ARROW_RIGHT: + case KeyType::ARROW_UP: + case KeyType::ARROW_DOWN: + case KeyType::ARROW_LEFT: + case KeyType::ARROW_RIGHT: $this->moveCursor($c); break; case chr(ctrl_key('l')): - case Key::ESCAPE: + case KeyType::ESCAPE: // Do nothing break; @@ -919,11 +917,11 @@ class Editor { private function pageUpOrDown(string $c): void { - if ($c === Key::PAGE_UP) + if ($c === KeyType::PAGE_UP) { $this->cursorY = $this->rowOffset; } - else if ($c === Key::PAGE_DOWN) + else if ($c === KeyType::PAGE_DOWN) { $this->cursorY = $this->rowOffset + $this->screenRows - 1; if ($this->cursorY > $this->numRows) @@ -935,7 +933,7 @@ class Editor { $times = $this->screenRows; 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); } } diff --git a/src/Enum/Event.php b/src/Enum/Event.php new file mode 100644 index 0000000..e297d51 --- /dev/null +++ b/src/Enum/Event.php @@ -0,0 +1,12 @@ +