Cut down on number of keycode escapes with constants
timw4mail/php-kilo/master This commit looks good Details

This commit is contained in:
Timothy Warren 2020-01-29 16:13:05 -05:00
parent a47b527a28
commit 60b1cca695
8 changed files with 52 additions and 46 deletions

View File

@ -177,7 +177,7 @@ class Editor {
$rx = 0;
for ($i = 0; $i < $cx; $i++)
{
if ($row->chars[$i] === "\t")
if ($row->chars[$i] === KeyCode::TAB)
{
$rx += (KILO_TAB_STOP - 1) - ($rx % KILO_TAB_STOP);
}
@ -192,7 +192,7 @@ class Editor {
$cur_rx = 0;
for ($cx = 0; $cx < $row->size; $cx++)
{
if ($row->chars[$cx] === "\t")
if ($row->chars[$cx] === KeyCode::TAB)
{
$cur_rx += (KILO_TAB_STOP - 1) - ($cur_rx % KILO_TAB_STOP);
}
@ -426,7 +426,7 @@ class Editor {
$savedHl = [];
}
if ($key === "\r" || $key === "\e")
if ($key === KeyCode::ENTER || $key === KeyCode::ESCAPE)
{
$lastMatch = -1;
$direction = 1;
@ -598,7 +598,7 @@ class Editor {
for ($i = 0; $i < $len; $i++)
{
// Handle 'non-printable' characters
if (is_cntrl($c[$i]))
if (is_ctrl($c[$i]))
{
$sym = (ord($c[$i]) <= 26)
? chr(ord('@') + ord($c[$i]))
@ -760,7 +760,7 @@ class Editor {
{
$buffer = substr($buffer, 0, -1);
}
else if (is_ascii($c) && ( ! is_cntrl($c)) && ! in_array($c, $modifiers, TRUE))
else if (is_ascii($c) && ( ! is_ctrl($c)) && ! in_array($c, $modifiers, TRUE))
{
$buffer .= $c;
}
@ -835,7 +835,7 @@ class Editor {
$c = $this->readKey();
if ($c === "\0" || $c === '')
if ($c === KeyCode::NULL || $c === KeyCode::EMPTY)
{
return '';
}

View File

@ -1,12 +0,0 @@
<?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';
}

View File

@ -12,9 +12,17 @@ class KeyCode {
public const ARROW_RIGHT = "\e[C";
public const ARROW_UP = "\e[A";
public const BACKSPACE = "\x7f";
public const CARRIAGE_RETURN = "\r";
public const DEL_KEY = "\e[3~";
public const EMPTY = '';
public const ENTER = "\r";
public const ESCAPE = "\e";
public const FORM_FEED = "\f";
public const NEWLINE = "\n";
public const NULL = "\0";
public const PAGE_DOWN = "\e[6~";
public const PAGE_UP = "\e[5~";
public const SPACE = ' ';
public const TAB = "\t";
public const VERTICAL_TAB = "\v";
}

View File

@ -2,9 +2,18 @@
namespace Aviat\Kilo;
use Aviat\Kilo\Enum\Event as EventEnum;
class Event {
use Traits\ConstList;
// ------------------------------------------------------------------------
// Valid Events
// ------------------------------------------------------------------------
public const INPUT_KEY = 'INPUT_KEY';
public const PAGE_CHANGE = 'PAGE_CHANGE';
public const MOVE_CURSOR = 'MOVE_CURSOR';
public const QUIT_ATTEMPT = 'QUIT_ATTEMPT';
// Mapping of events to handlers
private static $subscribeMap = [];
public static function fire(string $eventName, $value): void
@ -20,7 +29,7 @@ class Event {
}
}
public static function bind(string $eventName, callable $fn): void
public static function on(string $eventName, callable $fn): void
{
static::validateEvent($eventName);
@ -37,11 +46,11 @@ class Event {
private static function validateEvent(string $eventName): void
{
$validEvents = EventEnum::getConstList();
$validEvents = self::getConstList();
if ( ! array_key_exists($eventName, $validEvents))
{
throw new \InvalidArgumentException("Invalid event '{$eventName}'. Event const must exist in Aviat\\Kilo\\Enum\\Event.");
throw new \InvalidArgumentException("Invalid event '{$eventName}'. Event const must exist in Aviat\\Kilo\\Event.");
}
}
}

View File

@ -3,6 +3,7 @@
namespace Aviat\Kilo;
use Aviat\Kilo\Enum\Highlight;
use Aviat\Kilo\Enum\KeyCode;
/**
* @property-read int size
@ -413,7 +414,7 @@ class Row {
$klen = strlen($k);
$nextCharOffset = $i + $klen;
$isEndOfLine = $nextCharOffset >= $this->rsize;
$nextChar = ($isEndOfLine) ? "\0" : $this->render[$nextCharOffset];
$nextChar = ($isEndOfLine) ? KeyCode::NULL : $this->render[$nextCharOffset];
if (substr($this->render, $i, $klen) === $k && is_separator($nextChar))
{

View File

@ -4,11 +4,7 @@ namespace Aviat\Kilo;
use FFI;
use Aviat\Kilo\Enum\{
C,
Color,
Highlight,
};
use Aviat\Kilo\Enum\{C, Color, Highlight, KeyCode};
/**
* See if tput exists for fallback terminal size detection
@ -18,7 +14,7 @@ use Aviat\Kilo\Enum\{
*/
function has_tput(): bool
{
return strpos(shell_exec('type tput'), ' is ') !== FALSE;
return str_contains(shell_exec('type tput'), ' is ');
}
// ----------------------------------------------------------------------------
@ -104,7 +100,7 @@ function is_ascii(string $single_char): bool
* @param string $char
* @return bool
*/
function is_cntrl(string $char): bool
function is_ctrl(string $char): bool
{
$c = ord($char);
return is_ascii($char) && ( $c === 0x7f || $c < 0x20 );
@ -130,7 +126,14 @@ function is_digit(string $char): bool
*/
function is_space(string $char): bool
{
$ws = [' ', "\t", "\n", "\r", "\v", "\f"];
$ws = [
KeyCode::CARRIAGE_RETURN,
KeyCode::FORM_FEED,
KeyCode::NEWLINE,
KeyCode::SPACE,
KeyCode::TAB,
KeyCode::VERTICAL_TAB,
];
return is_ascii($char) && in_array($char, $ws, TRUE);
}
@ -168,11 +171,9 @@ function is_separator(string $char): bool
return FALSE;
}
// `strpos` is used instead of `strchr`/`strstr` as we don't care about the actual match
// while `strchr` would match the C version, it also returns the match
$isSep = (strpos(',.()+-/*=~%<>[];', $char) !== FALSE);
$isSep = str_contains(',.()+-/*=~%<>[];', $char);
return is_space($char) || $char === "\0" || $isSep;
return is_space($char) || $char === KeyCode::NULL || $isSep;
}
/**
@ -287,7 +288,7 @@ function syntax_to_color(int $hl): int
*/
function tabs_to_spaces(string $str, ?int $number = KILO_TAB_STOP): string
{
return str_replace("\t", str_repeat(' ', $number), $str);
return str_replace(KeyCode::TAB, str_repeat(KeyCode::SPACE, $number), $str);
}
/**

View File

@ -3,7 +3,6 @@
namespace Aviat\Kilo\Tests;
use Aviat\Kilo\Event;
use Aviat\Kilo\Enum\Event as EventType;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
@ -11,7 +10,7 @@ class EventTest extends TestCase {
public function testRequiresValidEvent(): void
{
$this->expectException(InvalidArgumentException::class);
Event::bind('badEventName', fn () => null);
Event::on('badEventName', fn () => null);
$this->expectException(InvalidArgumentException::class);
Event::fire('badEventName', []);
@ -22,7 +21,7 @@ class EventTest extends TestCase {
$fn = static function($value = false) {
static::assertTrue($value);
};
Event::bind(EventType::INPUT_KEY, $fn);
Event::fire(EventType::INPUT_KEY, TRUE);
Event::on(Event::INPUT_KEY, $fn);
Event::fire(Event::INPUT_KEY, TRUE);
}
}

View File

@ -11,7 +11,7 @@ use function Aviat\Kilo\ctrl_key;
use function Aviat\Kilo\get_file_syntax_map;
use function Aviat\Kilo\get_window_size;
use function Aviat\Kilo\is_ascii;
use function Aviat\Kilo\is_cntrl;
use function Aviat\Kilo\is_ctrl;
use function Aviat\Kilo\is_digit;
use function Aviat\Kilo\is_separator;
use function Aviat\Kilo\is_space;
@ -42,22 +42,22 @@ class FunctionTest extends TestCase {
$this->assertEquals(0x01, ctrl_key('a'));
}
public function test_is_cntrl(): void
public function test_is_ctrl(): void
{
for ($i = 0x0; $i < 0x20; $i++)
{
$char = chr($i);
$this->assertTrue(is_cntrl($char), 'Should be a control character');
$this->assertTrue(is_ctrl($char), 'Should be a control character');
}
for ($n = 0x20; $n < 0x7f; $n++)
{
$char = chr($n);
$this->assertFalse(is_cntrl($char), 'Should not be a control character');
$this->assertFalse(is_ctrl($char), 'Should not be a control character');
}
// Escape, code 7f, is an outlier
$this->assertTrue(is_cntrl(chr(0x7f)));
$this->assertTrue(is_ctrl(chr(0x7f)));
}
public function test_is_space(): void