A little cleanup refactoring
This commit is contained in:
parent
99c5ac9697
commit
a3e902967a
@ -13,7 +13,7 @@ use Aviat\Kilo\Tokens\PHP;
|
|||||||
* @property-read int numRows
|
* @property-read int numRows
|
||||||
*/
|
*/
|
||||||
class Editor {
|
class Editor {
|
||||||
use MagicProperties;
|
use Traits\MagicProperties;
|
||||||
|
|
||||||
private string $ab = '';
|
private string $ab = '';
|
||||||
|
|
||||||
@ -51,6 +51,7 @@ class Editor {
|
|||||||
|
|
||||||
[$this->screenRows, $this->screenCols] = get_window_size();
|
[$this->screenRows, $this->screenCols] = get_window_size();
|
||||||
|
|
||||||
|
// Remove a row for the status bar, and one for the message bar
|
||||||
$this->screenRows -= 2;
|
$this->screenRows -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +222,7 @@ class Editor {
|
|||||||
$this->dirty++;
|
$this->dirty++;
|
||||||
|
|
||||||
// Re-tokenize the file
|
// Re-tokenize the file
|
||||||
if ($updateSyntax && $this->syntax->filetype === 'PHP')
|
if ($updateSyntax)
|
||||||
{
|
{
|
||||||
$this->refreshPHPSyntax();
|
$this->refreshPHPSyntax();
|
||||||
}
|
}
|
||||||
@ -245,10 +246,7 @@ class Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Re-tokenize the file
|
// Re-tokenize the file
|
||||||
if ($this->syntax->filetype === 'PHP')
|
|
||||||
{
|
|
||||||
$this->refreshPHPSyntax();
|
$this->refreshPHPSyntax();
|
||||||
}
|
|
||||||
|
|
||||||
$this->dirty++;
|
$this->dirty++;
|
||||||
}
|
}
|
||||||
@ -266,10 +264,7 @@ class Editor {
|
|||||||
$this->rows[$this->cursorY]->insertChar($this->cursorX, $c);
|
$this->rows[$this->cursorY]->insertChar($this->cursorX, $c);
|
||||||
|
|
||||||
// Re-tokenize the file
|
// Re-tokenize the file
|
||||||
if ($this->syntax->filetype === 'PHP')
|
|
||||||
{
|
|
||||||
$this->refreshPHPSyntax();
|
$this->refreshPHPSyntax();
|
||||||
}
|
|
||||||
|
|
||||||
$this->cursorX++;
|
$this->cursorX++;
|
||||||
}
|
}
|
||||||
@ -297,11 +292,8 @@ class Editor {
|
|||||||
$this->cursorX = 0;
|
$this->cursorX = 0;
|
||||||
|
|
||||||
// Re-tokenize the file
|
// Re-tokenize the file
|
||||||
if ($this->syntax->filetype === 'PHP')
|
|
||||||
{
|
|
||||||
$this->refreshPHPSyntax();
|
$this->refreshPHPSyntax();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected function deleteChar(): void
|
protected function deleteChar(): void
|
||||||
{
|
{
|
||||||
@ -325,11 +317,8 @@ class Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Re-tokenize the file
|
// Re-tokenize the file
|
||||||
if ($this->syntax->filetype === 'PHP')
|
|
||||||
{
|
|
||||||
$this->refreshPHPSyntax();
|
$this->refreshPHPSyntax();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// ! File I/O
|
// ! File I/O
|
||||||
@ -931,6 +920,11 @@ class Editor {
|
|||||||
|
|
||||||
private function refreshPHPSyntax(): void
|
private function refreshPHPSyntax(): void
|
||||||
{
|
{
|
||||||
|
if ($this->syntax->filetype !== 'PHP')
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$this->tokens = PHP::getTokens($this->rowsToString());
|
$this->tokens = PHP::getTokens($this->rowsToString());
|
||||||
for ($i = 0; $i < $this->numRows; $i++)
|
for ($i = 0; $i < $this->numRows; $i++)
|
||||||
{
|
{
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
namespace Aviat\Kilo\Enum;
|
namespace Aviat\Kilo\Enum;
|
||||||
|
|
||||||
|
use Aviat\Kilo\Traits;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just a namespace for C language constants
|
* Just a namespace for C language constants
|
||||||
*/
|
*/
|
||||||
class C {
|
class C {
|
||||||
use ConstList;
|
use Traits\ConstList;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// ! Misc I/O constants
|
// ! Misc I/O constants
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
namespace Aviat\Kilo\Enum;
|
namespace Aviat\Kilo\Enum;
|
||||||
|
|
||||||
|
use Aviat\Kilo\Traits;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ANSI Color escape sequences
|
* ANSI Color escape sequences
|
||||||
*/
|
*/
|
||||||
class Color {
|
class Color {
|
||||||
use ConstList;
|
use Traits\ConstList;
|
||||||
|
|
||||||
// Foreground colors
|
// Foreground colors
|
||||||
public const FG_BLACK = 30;
|
public const FG_BLACK = 30;
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
namespace Aviat\Kilo\Enum;
|
namespace Aviat\Kilo\Enum;
|
||||||
|
|
||||||
|
use Aviat\Kilo\Traits;
|
||||||
|
|
||||||
class Highlight {
|
class Highlight {
|
||||||
use ConstList;
|
use Traits\ConstList;
|
||||||
|
|
||||||
public const NORMAL = 0;
|
public const NORMAL = 0;
|
||||||
public const COMMENT = 1;
|
public const COMMENT = 1;
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
namespace Aviat\Kilo\Enum;
|
namespace Aviat\Kilo\Enum;
|
||||||
|
|
||||||
|
use Aviat\Kilo\Traits;
|
||||||
|
|
||||||
class Key {
|
class Key {
|
||||||
use ConstList;
|
use Traits\ConstList;
|
||||||
|
|
||||||
public const ARROW_DOWN = 'ARROW_DOWN';
|
public const ARROW_DOWN = 'ARROW_DOWN';
|
||||||
public const ARROW_LEFT = 'ARROW_LEFT';
|
public const ARROW_LEFT = 'ARROW_LEFT';
|
||||||
|
@ -9,7 +9,7 @@ use Aviat\Kilo\Enum\Highlight;
|
|||||||
* @property-read int rsize
|
* @property-read int rsize
|
||||||
*/
|
*/
|
||||||
class Row {
|
class Row {
|
||||||
use MagicProperties;
|
use Traits\MagicProperties;
|
||||||
|
|
||||||
private string $chars = '';
|
private string $chars = '';
|
||||||
public string $render = '';
|
public string $render = '';
|
||||||
|
@ -18,22 +18,31 @@ class Termios {
|
|||||||
$ffi = get_ffi();
|
$ffi = get_ffi();
|
||||||
$termios = $ffi->new('struct termios');
|
$termios = $ffi->new('struct termios');
|
||||||
$res = $ffi->tcgetattr(C::STDIN_FILENO, FFI::addr($termios));
|
$res = $ffi->tcgetattr(C::STDIN_FILENO, FFI::addr($termios));
|
||||||
|
|
||||||
if ($res === -1)
|
if ($res === -1)
|
||||||
{
|
{
|
||||||
die('Failed to get terminal settings');
|
throw new TermiosException('Failed to get existing terminal settings');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->originalTermios = $termios;
|
$this->originalTermios = $termios;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function enableRawMode(): void
|
/**
|
||||||
|
* Put the current terminal into raw input mode
|
||||||
|
*
|
||||||
|
* Returns TRUE if successful. Will return NULL if run more than once, as
|
||||||
|
* raw mode is pretty binary...there's no point in reapplying raw mode!
|
||||||
|
*
|
||||||
|
* @return bool|null
|
||||||
|
*/
|
||||||
|
public static function enableRawMode(): ?bool
|
||||||
{
|
{
|
||||||
static $run = FALSE;
|
static $run = FALSE;
|
||||||
|
|
||||||
// Don't run this more than once!
|
// Don't run this more than once!
|
||||||
if ($run === TRUE)
|
if ($run === TRUE)
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
$run = TRUE;
|
$run = TRUE;
|
||||||
@ -55,13 +64,19 @@ class Termios {
|
|||||||
|
|
||||||
// Turn on raw mode
|
// Turn on raw mode
|
||||||
$res = get_ffi()->tcsetattr(C::STDIN_FILENO, C::TCSAFLUSH, FFI::addr($termios));
|
$res = get_ffi()->tcsetattr(C::STDIN_FILENO, C::TCSAFLUSH, FFI::addr($termios));
|
||||||
if ($res === -1)
|
|
||||||
{
|
return $res !== -1;
|
||||||
die('Failed to set raw mode');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function disableRawMode(): void
|
/**
|
||||||
|
* Restores terminal settings that were changed when going into raw mode.
|
||||||
|
*
|
||||||
|
* Returns TRUE if settings are applied successfully. If raw mode was not
|
||||||
|
* enabled, this will output a line of escape codes and a new line.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function disableRawMode(): bool
|
||||||
{
|
{
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
|
|
||||||
@ -71,10 +86,7 @@ class Termios {
|
|||||||
|
|
||||||
$res = get_ffi()->tcsetattr(C::STDIN_FILENO, C::TCSAFLUSH, FFI::addr($instance->originalTermios));
|
$res = get_ffi()->tcsetattr(C::STDIN_FILENO, C::TCSAFLUSH, FFI::addr($instance->originalTermios));
|
||||||
|
|
||||||
if ($res === -1)
|
return $res !== -1;
|
||||||
{
|
|
||||||
die('Failed to restore terminal settings');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getInstance(): self
|
private static function getInstance(): self
|
||||||
|
12
src/TermiosException.php
Normal file
12
src/TermiosException.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Aviat\Kilo;
|
||||||
|
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class TermiosException extends \UnexpectedValueException {
|
||||||
|
public function __construct($message = 'Failed to apply terminal settings', $code = 0, Throwable $previous = NULL)
|
||||||
|
{
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
|
}
|
@ -47,7 +47,7 @@ class PHP {
|
|||||||
*/
|
*/
|
||||||
public static function getFileTokens(string $filename): array
|
public static function getFileTokens(string $filename): array
|
||||||
{
|
{
|
||||||
$code = file_get_contents($filename);
|
$code = @file_get_contents($filename);
|
||||||
|
|
||||||
if ($code === FALSE)
|
if ($code === FALSE)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
namespace Aviat\Kilo\Enum;
|
namespace Aviat\Kilo\Traits;
|
||||||
|
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
namespace Aviat\Kilo;
|
namespace Aviat\Kilo\Traits;
|
||||||
|
|
||||||
trait MagicProperties {
|
trait MagicProperties {
|
||||||
abstract public function __get(string $name);
|
abstract public function __get(string $name);
|
@ -6,16 +6,26 @@ use Aviat\Kilo\Tokens\PHP;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class PHPTest extends TestCase {
|
class PHPTest extends TestCase {
|
||||||
public function testGetTokens(): void
|
public function testGetFileTokens(): void
|
||||||
{
|
{
|
||||||
$file = file_get_contents(realpath(__DIR__ . '/../../test.php'));
|
$filename = realpath(__DIR__ . '/../../test.php');
|
||||||
$tokens = PHP::getTokens($file);
|
$file = file_get_contents($filename);
|
||||||
|
$tokens = PHP::getFileTokens($filename);
|
||||||
$this->assertNotEmpty($file);
|
|
||||||
|
|
||||||
$lines = explode("\n", $file);
|
$lines = explode("\n", $file);
|
||||||
array_unshift($lines, '');
|
array_unshift($lines, '');
|
||||||
|
|
||||||
|
$this->verifyTokens($tokens, $lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetFileTokensEmptyFile(): void
|
||||||
|
{
|
||||||
|
$filename = __DIR__ . '/../../foobarbaz.php';
|
||||||
|
$this->assertEmpty(PHP::getFileTokens($filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function verifyTokens(array $tokens, array $lines): void
|
||||||
|
{
|
||||||
$misplacedTokens = [];
|
$misplacedTokens = [];
|
||||||
|
|
||||||
foreach ($tokens as $index => $lineTokens)
|
foreach ($tokens as $index => $lineTokens)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
namespace Aviat\Kilo\Tests\Enum;
|
namespace Aviat\Kilo\Tests\Traits;
|
||||||
|
|
||||||
use Aviat\Kilo\Enum\ConstList;
|
use Aviat\Kilo\Traits\ConstList;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class ConstListTest extends TestCase {
|
class ConstListTest extends TestCase {
|
Loading…
Reference in New Issue
Block a user