104 lines
1.7 KiB
PHP
104 lines
1.7 KiB
PHP
|
<?php declare(strict_types=1);
|
||
|
|
||
|
namespace Kilo;
|
||
|
|
||
|
/**
|
||
|
* @property-read int size
|
||
|
* @property-read int rsize
|
||
|
*/
|
||
|
class Row {
|
||
|
use MagicProperties;
|
||
|
|
||
|
public string $chars = '';
|
||
|
public string $render = '';
|
||
|
|
||
|
public array $hl = [];
|
||
|
|
||
|
public static function new(string $chars): self
|
||
|
{
|
||
|
return new self($chars);
|
||
|
}
|
||
|
|
||
|
private function __construct($chars)
|
||
|
{
|
||
|
$this->chars = $chars;
|
||
|
}
|
||
|
|
||
|
public function __get(string $name)
|
||
|
{
|
||
|
switch ($name)
|
||
|
{
|
||
|
case 'size':
|
||
|
return strlen($this->chars);
|
||
|
|
||
|
case 'rsize':
|
||
|
return strlen($this->render);
|
||
|
|
||
|
default:
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function __toString(): string
|
||
|
{
|
||
|
return $this->chars . "\n";
|
||
|
}
|
||
|
|
||
|
public function update(): void
|
||
|
{
|
||
|
$idx = 0;
|
||
|
|
||
|
for ($i = 0; $i < $this->size; $i++)
|
||
|
{
|
||
|
if ($this->chars[$i] === "\t")
|
||
|
{
|
||
|
$this->render[$idx++] = ' ';
|
||
|
while ($idx % KILO_TAB_STOP !== 0)
|
||
|
{
|
||
|
$this->render[$idx++] = ' ';
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$this->render[$idx++] = $this->chars[$i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$this->updateSyntax();
|
||
|
}
|
||
|
|
||
|
// ------------------------------------------------------------------------
|
||
|
// ! Syntax Highlighting
|
||
|
// ------------------------------------------------------------------------
|
||
|
|
||
|
protected function updateSyntax(): void
|
||
|
{
|
||
|
$this->hl = array_fill(0, $this->rsize, Highlight::NORMAL);
|
||
|
|
||
|
$prevSep = TRUE;
|
||
|
|
||
|
$i = 0;
|
||
|
|
||
|
while ($i < $this->rsize)
|
||
|
{
|
||
|
$char = $this->render[$i];
|
||
|
$prevHl = ($i > 0) ? $this->hl[$i - 1] : Highlight::NORMAL;
|
||
|
|
||
|
// Numbers, including decimal points
|
||
|
if (
|
||
|
($char === '.' && $prevHl === Highlight::NUMBER) ||
|
||
|
(($prevSep || $prevHl === Highlight::NUMBER) && is_digit($char))
|
||
|
)
|
||
|
{
|
||
|
$this->hl[$i] = Highlight::NUMBER;
|
||
|
$i++;
|
||
|
$prevSep = FALSE;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$prevSep = is_separator($char);
|
||
|
$i++;
|
||
|
}
|
||
|
}
|
||
|
}
|