Cut down on number of keycode escapes with constants
All checks were successful
timw4mail/php-kilo/master This commit looks good
All checks were successful
timw4mail/php-kilo/master This commit looks good
This commit is contained in:
parent
a47b527a28
commit
60b1cca695
@ -177,7 +177,7 @@ class Editor {
|
|||||||
$rx = 0;
|
$rx = 0;
|
||||||
for ($i = 0; $i < $cx; $i++)
|
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);
|
$rx += (KILO_TAB_STOP - 1) - ($rx % KILO_TAB_STOP);
|
||||||
}
|
}
|
||||||
@ -192,7 +192,7 @@ class Editor {
|
|||||||
$cur_rx = 0;
|
$cur_rx = 0;
|
||||||
for ($cx = 0; $cx < $row->size; $cx++)
|
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);
|
$cur_rx += (KILO_TAB_STOP - 1) - ($cur_rx % KILO_TAB_STOP);
|
||||||
}
|
}
|
||||||
@ -426,7 +426,7 @@ class Editor {
|
|||||||
$savedHl = [];
|
$savedHl = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($key === "\r" || $key === "\e")
|
if ($key === KeyCode::ENTER || $key === KeyCode::ESCAPE)
|
||||||
{
|
{
|
||||||
$lastMatch = -1;
|
$lastMatch = -1;
|
||||||
$direction = 1;
|
$direction = 1;
|
||||||
@ -598,7 +598,7 @@ class Editor {
|
|||||||
for ($i = 0; $i < $len; $i++)
|
for ($i = 0; $i < $len; $i++)
|
||||||
{
|
{
|
||||||
// Handle 'non-printable' characters
|
// Handle 'non-printable' characters
|
||||||
if (is_cntrl($c[$i]))
|
if (is_ctrl($c[$i]))
|
||||||
{
|
{
|
||||||
$sym = (ord($c[$i]) <= 26)
|
$sym = (ord($c[$i]) <= 26)
|
||||||
? chr(ord('@') + ord($c[$i]))
|
? chr(ord('@') + ord($c[$i]))
|
||||||
@ -760,7 +760,7 @@ class Editor {
|
|||||||
{
|
{
|
||||||
$buffer = substr($buffer, 0, -1);
|
$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;
|
$buffer .= $c;
|
||||||
}
|
}
|
||||||
@ -835,7 +835,7 @@ class Editor {
|
|||||||
|
|
||||||
$c = $this->readKey();
|
$c = $this->readKey();
|
||||||
|
|
||||||
if ($c === "\0" || $c === '')
|
if ($c === KeyCode::NULL || $c === KeyCode::EMPTY)
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -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';
|
|
||||||
}
|
|
@ -12,9 +12,17 @@ class KeyCode {
|
|||||||
public const ARROW_RIGHT = "\e[C";
|
public const ARROW_RIGHT = "\e[C";
|
||||||
public const ARROW_UP = "\e[A";
|
public const ARROW_UP = "\e[A";
|
||||||
public const BACKSPACE = "\x7f";
|
public const BACKSPACE = "\x7f";
|
||||||
|
public const CARRIAGE_RETURN = "\r";
|
||||||
public const DEL_KEY = "\e[3~";
|
public const DEL_KEY = "\e[3~";
|
||||||
|
public const EMPTY = '';
|
||||||
public const ENTER = "\r";
|
public const ENTER = "\r";
|
||||||
public const ESCAPE = "\e";
|
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_DOWN = "\e[6~";
|
||||||
public const PAGE_UP = "\e[5~";
|
public const PAGE_UP = "\e[5~";
|
||||||
|
public const SPACE = ' ';
|
||||||
|
public const TAB = "\t";
|
||||||
|
public const VERTICAL_TAB = "\v";
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,18 @@
|
|||||||
|
|
||||||
namespace Aviat\Kilo;
|
namespace Aviat\Kilo;
|
||||||
|
|
||||||
use Aviat\Kilo\Enum\Event as EventEnum;
|
|
||||||
|
|
||||||
class Event {
|
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 = [];
|
private static $subscribeMap = [];
|
||||||
|
|
||||||
public static function fire(string $eventName, $value): void
|
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);
|
static::validateEvent($eventName);
|
||||||
|
|
||||||
@ -37,11 +46,11 @@ class Event {
|
|||||||
|
|
||||||
private static function validateEvent(string $eventName): void
|
private static function validateEvent(string $eventName): void
|
||||||
{
|
{
|
||||||
$validEvents = EventEnum::getConstList();
|
$validEvents = self::getConstList();
|
||||||
|
|
||||||
if ( ! array_key_exists($eventName, $validEvents))
|
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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,6 +3,7 @@
|
|||||||
namespace Aviat\Kilo;
|
namespace Aviat\Kilo;
|
||||||
|
|
||||||
use Aviat\Kilo\Enum\Highlight;
|
use Aviat\Kilo\Enum\Highlight;
|
||||||
|
use Aviat\Kilo\Enum\KeyCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property-read int size
|
* @property-read int size
|
||||||
@ -413,7 +414,7 @@ class Row {
|
|||||||
$klen = strlen($k);
|
$klen = strlen($k);
|
||||||
$nextCharOffset = $i + $klen;
|
$nextCharOffset = $i + $klen;
|
||||||
$isEndOfLine = $nextCharOffset >= $this->rsize;
|
$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))
|
if (substr($this->render, $i, $klen) === $k && is_separator($nextChar))
|
||||||
{
|
{
|
||||||
|
@ -4,11 +4,7 @@ namespace Aviat\Kilo;
|
|||||||
|
|
||||||
use FFI;
|
use FFI;
|
||||||
|
|
||||||
use Aviat\Kilo\Enum\{
|
use Aviat\Kilo\Enum\{C, Color, Highlight, KeyCode};
|
||||||
C,
|
|
||||||
Color,
|
|
||||||
Highlight,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See if tput exists for fallback terminal size detection
|
* See if tput exists for fallback terminal size detection
|
||||||
@ -18,7 +14,7 @@ use Aviat\Kilo\Enum\{
|
|||||||
*/
|
*/
|
||||||
function has_tput(): bool
|
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
|
* @param string $char
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function is_cntrl(string $char): bool
|
function is_ctrl(string $char): bool
|
||||||
{
|
{
|
||||||
$c = ord($char);
|
$c = ord($char);
|
||||||
return is_ascii($char) && ( $c === 0x7f || $c < 0x20 );
|
return is_ascii($char) && ( $c === 0x7f || $c < 0x20 );
|
||||||
@ -130,7 +126,14 @@ function is_digit(string $char): bool
|
|||||||
*/
|
*/
|
||||||
function is_space(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);
|
return is_ascii($char) && in_array($char, $ws, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,11 +171,9 @@ function is_separator(string $char): bool
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// `strpos` is used instead of `strchr`/`strstr` as we don't care about the actual match
|
$isSep = str_contains(',.()+-/*=~%<>[];', $char);
|
||||||
// while `strchr` would match the C version, it also returns the match
|
|
||||||
$isSep = (strpos(',.()+-/*=~%<>[];', $char) !== FALSE);
|
|
||||||
|
|
||||||
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
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace Aviat\Kilo\Tests;
|
namespace Aviat\Kilo\Tests;
|
||||||
|
|
||||||
use Aviat\Kilo\Event;
|
use Aviat\Kilo\Event;
|
||||||
use Aviat\Kilo\Enum\Event as EventType;
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
@ -11,7 +10,7 @@ class EventTest extends TestCase {
|
|||||||
public function testRequiresValidEvent(): void
|
public function testRequiresValidEvent(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
Event::bind('badEventName', fn () => null);
|
Event::on('badEventName', fn () => null);
|
||||||
|
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
Event::fire('badEventName', []);
|
Event::fire('badEventName', []);
|
||||||
@ -22,7 +21,7 @@ class EventTest extends TestCase {
|
|||||||
$fn = static function($value = false) {
|
$fn = static function($value = false) {
|
||||||
static::assertTrue($value);
|
static::assertTrue($value);
|
||||||
};
|
};
|
||||||
Event::bind(EventType::INPUT_KEY, $fn);
|
Event::on(Event::INPUT_KEY, $fn);
|
||||||
Event::fire(EventType::INPUT_KEY, TRUE);
|
Event::fire(Event::INPUT_KEY, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use function Aviat\Kilo\ctrl_key;
|
|||||||
use function Aviat\Kilo\get_file_syntax_map;
|
use function Aviat\Kilo\get_file_syntax_map;
|
||||||
use function Aviat\Kilo\get_window_size;
|
use function Aviat\Kilo\get_window_size;
|
||||||
use function Aviat\Kilo\is_ascii;
|
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_digit;
|
||||||
use function Aviat\Kilo\is_separator;
|
use function Aviat\Kilo\is_separator;
|
||||||
use function Aviat\Kilo\is_space;
|
use function Aviat\Kilo\is_space;
|
||||||
@ -42,22 +42,22 @@ class FunctionTest extends TestCase {
|
|||||||
$this->assertEquals(0x01, ctrl_key('a'));
|
$this->assertEquals(0x01, ctrl_key('a'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_is_cntrl(): void
|
public function test_is_ctrl(): void
|
||||||
{
|
{
|
||||||
for ($i = 0x0; $i < 0x20; $i++)
|
for ($i = 0x0; $i < 0x20; $i++)
|
||||||
{
|
{
|
||||||
$char = chr($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++)
|
for ($n = 0x20; $n < 0x7f; $n++)
|
||||||
{
|
{
|
||||||
$char = chr($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
|
// Escape, code 7f, is an outlier
|
||||||
$this->assertTrue(is_cntrl(chr(0x7f)));
|
$this->assertTrue(is_ctrl(chr(0x7f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_is_space(): void
|
public function test_is_space(): void
|
||||||
|
Loading…
Reference in New Issue
Block a user