2019-10-24 16:57:27 -04:00
|
|
|
<?php declare(strict_types=1);
|
|
|
|
|
2019-11-08 16:27:08 -05:00
|
|
|
namespace Aviat\Kilo;
|
|
|
|
|
|
|
|
use Aviat\Kilo\Enum\Highlight;
|
2021-04-09 13:52:01 -04:00
|
|
|
use Aviat\Kilo\Enum\RawKeyCode;
|
2019-10-24 16:57:27 -04:00
|
|
|
|
|
|
|
/**
|
2021-03-03 16:35:58 -05:00
|
|
|
* @property-read int $size
|
|
|
|
* @property-read int $rsize
|
2021-03-18 16:26:30 -04:00
|
|
|
* @property string $chars
|
2019-10-24 16:57:27 -04:00
|
|
|
*/
|
|
|
|
class Row {
|
2019-11-19 15:57:51 -05:00
|
|
|
use Traits\MagicProperties;
|
2019-10-24 16:57:27 -04:00
|
|
|
|
2021-03-18 16:26:30 -04:00
|
|
|
/**
|
|
|
|
* The version of the row to be displayed (where tabs are converted to display spaces)
|
|
|
|
*/
|
2019-10-24 16:57:27 -04:00
|
|
|
public string $render = '';
|
|
|
|
|
2021-03-18 16:26:30 -04:00
|
|
|
/**
|
|
|
|
* The mapping of characters to their highlighting type
|
|
|
|
*/
|
2019-10-25 16:36:03 -04:00
|
|
|
public array $hl = [];
|
|
|
|
|
|
|
|
private bool $hlOpenComment = FALSE;
|
2019-10-25 10:28:15 -04:00
|
|
|
|
2019-11-15 16:19:34 -05:00
|
|
|
private const T_RAW = -1;
|
|
|
|
|
2021-03-17 08:52:17 -04:00
|
|
|
public static function new(Document $parent, string $chars, int $idx): self
|
2019-10-24 16:57:27 -04:00
|
|
|
{
|
2021-03-18 16:26:30 -04:00
|
|
|
return new self(
|
|
|
|
$parent,
|
|
|
|
$chars,
|
|
|
|
$idx,
|
|
|
|
);
|
2019-10-24 16:57:27 -04:00
|
|
|
}
|
|
|
|
|
2021-03-18 16:26:30 -04:00
|
|
|
public static function default(): self
|
|
|
|
{
|
|
|
|
return new self(
|
|
|
|
Document::new(),
|
|
|
|
'',
|
|
|
|
0,
|
|
|
|
);
|
2021-03-09 13:37:03 -05:00
|
|
|
}
|
2019-10-25 10:28:15 -04:00
|
|
|
|
2021-03-18 16:26:30 -04:00
|
|
|
private function __construct(
|
|
|
|
/**
|
|
|
|
* The document that this row belongs to
|
|
|
|
*/
|
|
|
|
private Document $parent,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string The raw characters in the row
|
|
|
|
*/
|
|
|
|
private string $chars,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var int The line number of the current row
|
|
|
|
*/
|
|
|
|
public int $idx,
|
|
|
|
) {}
|
|
|
|
|
2021-03-03 16:35:58 -05:00
|
|
|
public function __get(string $name): mixed
|
2019-10-24 16:57:27 -04:00
|
|
|
{
|
2021-03-03 11:50:29 -05:00
|
|
|
return match ($name)
|
2019-10-24 16:57:27 -04:00
|
|
|
{
|
2021-03-03 11:50:29 -05:00
|
|
|
'size' => strlen($this->chars),
|
|
|
|
'rsize' => strlen($this->render),
|
|
|
|
'chars' => $this->chars,
|
|
|
|
default => NULL,
|
|
|
|
};
|
2019-10-24 16:57:27 -04:00
|
|
|
}
|
|
|
|
|
2021-03-03 16:35:58 -05:00
|
|
|
public function __set(string $name, mixed $value): void
|
2019-11-05 12:28:10 -05:00
|
|
|
{
|
2021-03-03 16:35:58 -05:00
|
|
|
if ($name === 'chars')
|
2019-11-05 12:28:10 -05:00
|
|
|
{
|
|
|
|
$this->chars = $value;
|
2021-03-17 13:14:16 -04:00
|
|
|
$this->highlight();
|
2019-11-05 12:28:10 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-24 16:57:27 -04:00
|
|
|
public function __toString(): string
|
|
|
|
{
|
|
|
|
return $this->chars . "\n";
|
|
|
|
}
|
|
|
|
|
2019-11-20 15:03:48 -05:00
|
|
|
public function __debugInfo(): array
|
2019-11-08 21:48:46 -05:00
|
|
|
{
|
|
|
|
return [
|
|
|
|
'size' => $this->size,
|
|
|
|
'rsize' => $this->rsize,
|
|
|
|
'chars' => $this->chars,
|
|
|
|
'render' => $this->render,
|
2019-11-15 16:19:34 -05:00
|
|
|
'hl' => $this->hl,
|
2019-11-08 21:48:46 -05:00
|
|
|
'hlOpenComment' => $this->hlOpenComment,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2021-03-18 16:26:30 -04:00
|
|
|
/**
|
|
|
|
* Is this row a valid part of a document?
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isValid(): bool
|
|
|
|
{
|
|
|
|
return ! $this->parent->isEmpty();
|
|
|
|
}
|
|
|
|
|
2021-03-17 13:14:16 -04:00
|
|
|
public function insert(int $at, string $c): void
|
2019-10-25 10:28:15 -04:00
|
|
|
{
|
|
|
|
if ($at < 0 || $at > $this->size)
|
|
|
|
{
|
2021-03-17 13:14:16 -04:00
|
|
|
$this->append($c);
|
2019-11-20 15:03:48 -05:00
|
|
|
return;
|
2019-10-25 10:28:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Safely insert into arbitrary position in the existing string
|
|
|
|
$this->chars = substr($this->chars, 0, $at) . $c . substr($this->chars, $at);
|
2021-03-17 13:14:16 -04:00
|
|
|
$this->highlight();
|
2019-10-25 10:28:15 -04:00
|
|
|
|
2021-03-10 22:47:57 -05:00
|
|
|
$this->parent->dirty = true;
|
2019-10-25 10:28:15 -04:00
|
|
|
}
|
|
|
|
|
2021-03-17 13:14:16 -04:00
|
|
|
public function append(string $s): void
|
2019-10-25 10:28:15 -04:00
|
|
|
{
|
|
|
|
$this->chars .= $s;
|
2021-03-17 13:14:16 -04:00
|
|
|
$this->highlight();
|
2019-10-25 10:28:15 -04:00
|
|
|
|
2021-03-10 22:47:57 -05:00
|
|
|
$this->parent->dirty = true;
|
2019-10-25 10:28:15 -04:00
|
|
|
}
|
|
|
|
|
2021-03-17 13:14:16 -04:00
|
|
|
public function delete(int $at): void
|
2019-10-25 10:28:15 -04:00
|
|
|
{
|
|
|
|
if ($at < 0 || $at >= $this->size)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->chars = substr_replace($this->chars, '', $at, 1);
|
2021-03-17 13:14:16 -04:00
|
|
|
$this->highlight();
|
2019-10-25 10:28:15 -04:00
|
|
|
|
2021-03-10 22:47:57 -05:00
|
|
|
$this->parent->dirty = true;
|
2019-10-25 10:28:15 -04:00
|
|
|
}
|
|
|
|
|
2021-03-17 13:14:16 -04:00
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// ! Syntax Highlighting
|
|
|
|
// ------------------------------------------------------------------------
|
2021-03-17 08:52:17 -04:00
|
|
|
|
2021-03-17 13:14:16 -04:00
|
|
|
public function highlight(): void
|
2019-10-24 16:57:27 -04:00
|
|
|
{
|
2019-11-08 13:32:31 -05:00
|
|
|
$this->render = tabs_to_spaces($this->chars);
|
2021-03-17 13:14:16 -04:00
|
|
|
$this->highlightGeneral();
|
2019-10-24 16:57:27 -04:00
|
|
|
}
|
|
|
|
|
2021-03-18 16:26:30 -04:00
|
|
|
protected function highlightComment(int $i, string $char): bool
|
|
|
|
{
|
|
|
|
$scs = $this->parent->fileType->syntax->singleLineCommentStart;
|
|
|
|
$scsLen = strlen($scs);
|
|
|
|
|
|
|
|
if ($scsLen > 0 && substr($this->render, $i, $scsLen) === $scs)
|
|
|
|
{
|
|
|
|
array_replace_range($this->hl, $i, $this->rsize - $i, Highlight::COMMENT);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function highlightString(int &$i): bool
|
|
|
|
{
|
|
|
|
$char = $this->render[$i];
|
|
|
|
$enabled = $this->parent->fileType->syntax->flags & Syntax::HIGHLIGHT_STRINGS;
|
|
|
|
|
|
|
|
if ($enabled && $char === '"' || $char === '\'')
|
|
|
|
{
|
|
|
|
$quote = $char;
|
|
|
|
$this->hl[$i] = Highlight::STRING;
|
|
|
|
$i++;
|
|
|
|
|
|
|
|
while ($i < $this->rsize)
|
|
|
|
{
|
|
|
|
$char = $this->render[$i];
|
|
|
|
$this->hl[$i] = Highlight::STRING;
|
|
|
|
|
|
|
|
// Check for escaped character
|
|
|
|
if ($char === '\\' && $i+1 < $this->rsize)
|
|
|
|
{
|
|
|
|
$this->hl[$i + 1] = Highlight::STRING;
|
|
|
|
$i += 2;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// End of the string!
|
|
|
|
if ($char === $quote)
|
|
|
|
{
|
|
|
|
$i++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-03-17 13:14:16 -04:00
|
|
|
protected function highlightGeneral(): void
|
2019-10-24 16:57:27 -04:00
|
|
|
{
|
|
|
|
$this->hl = array_fill(0, $this->rsize, Highlight::NORMAL);
|
|
|
|
|
2021-03-17 08:52:17 -04:00
|
|
|
if ($this->parent->fileType->name === 'PHP')
|
2019-10-29 17:02:03 -04:00
|
|
|
{
|
2021-03-17 08:52:17 -04:00
|
|
|
$this->highlightPHP();
|
2019-10-29 17:02:03 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-03-17 08:52:17 -04:00
|
|
|
$keywords1 = $this->parent->fileType->syntax->keywords1;
|
|
|
|
$keywords2 = $this->parent->fileType->syntax->keywords2;
|
2019-10-25 14:49:34 -04:00
|
|
|
|
2021-03-17 08:52:17 -04:00
|
|
|
$scs = $this->parent->fileType->syntax->singleLineCommentStart;
|
|
|
|
$mcs = $this->parent->fileType->syntax->multiLineCommentStart;
|
|
|
|
$mce = $this->parent->fileType->syntax->multiLineCommentEnd;
|
2019-10-25 16:36:03 -04:00
|
|
|
|
|
|
|
$scsLen = strlen($scs);
|
|
|
|
$mcsLen = strlen($mcs);
|
|
|
|
$mceLen = strlen($mce);
|
2019-10-25 12:08:21 -04:00
|
|
|
|
2019-10-24 16:57:27 -04:00
|
|
|
$prevSep = TRUE;
|
2019-10-25 11:49:04 -04:00
|
|
|
$inString = '';
|
2019-10-25 16:36:03 -04:00
|
|
|
$inComment = ($this->idx > 0 && $this->parent->rows[$this->idx - 1]->hlOpenComment);
|
2019-10-24 16:57:27 -04:00
|
|
|
|
|
|
|
$i = 0;
|
|
|
|
|
|
|
|
while ($i < $this->rsize)
|
|
|
|
{
|
|
|
|
$char = $this->render[$i];
|
|
|
|
$prevHl = ($i > 0) ? $this->hl[$i - 1] : Highlight::NORMAL;
|
|
|
|
|
2019-10-25 12:08:21 -04:00
|
|
|
// Single-line comments
|
2019-10-25 16:36:03 -04:00
|
|
|
if ($scsLen > 0 && $inString === '' && $inComment === FALSE
|
|
|
|
&& substr($this->render, $i, $scsLen) === $scs)
|
2019-10-25 12:08:21 -04:00
|
|
|
{
|
|
|
|
array_replace_range($this->hl, $i, $this->rsize - $i, Highlight::COMMENT);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-10-25 16:36:03 -04:00
|
|
|
// Multi-line comments
|
|
|
|
if ($mcsLen > 0 && $mceLen > 0 && $inString === '')
|
|
|
|
{
|
|
|
|
if ($inComment)
|
|
|
|
{
|
|
|
|
$this->hl[$i] = Highlight::ML_COMMENT;
|
|
|
|
if (substr($this->render, $i, $mceLen) === $mce)
|
|
|
|
{
|
|
|
|
array_replace_range($this->hl, $i, $mceLen, Highlight::ML_COMMENT);
|
|
|
|
$i += $mceLen;
|
|
|
|
$inComment = FALSE;
|
|
|
|
$prevSep = TRUE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$i++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (substr($this->render, $i, $mcsLen) === $mcs)
|
|
|
|
{
|
|
|
|
array_replace_range($this->hl, $i, $mcsLen, Highlight::ML_COMMENT);
|
|
|
|
$i += $mcsLen;
|
|
|
|
$inComment = TRUE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-25 12:08:21 -04:00
|
|
|
// String/Char literals
|
2021-03-18 16:26:30 -04:00
|
|
|
$this->highlightString($i);
|
2019-10-25 11:49:04 -04:00
|
|
|
|
2019-10-25 12:08:21 -04:00
|
|
|
// Numbers, including decimal points
|
2021-03-17 08:52:17 -04:00
|
|
|
if ($this->parent->fileType->syntax->flags & Syntax::HIGHLIGHT_NUMBERS)
|
2019-10-24 16:57:27 -04:00
|
|
|
{
|
2019-10-25 10:28:15 -04:00
|
|
|
if (
|
|
|
|
($char === '.' && $prevHl === Highlight::NUMBER) ||
|
|
|
|
(($prevSep || $prevHl === Highlight::NUMBER) && is_digit($char))
|
|
|
|
)
|
|
|
|
{
|
|
|
|
$this->hl[$i] = Highlight::NUMBER;
|
|
|
|
$i++;
|
|
|
|
$prevSep = FALSE;
|
|
|
|
continue;
|
|
|
|
}
|
2019-10-24 16:57:27 -04:00
|
|
|
}
|
|
|
|
|
2019-10-25 14:49:34 -04:00
|
|
|
// Keywords
|
|
|
|
if ($prevSep)
|
|
|
|
{
|
2019-11-05 12:28:10 -05:00
|
|
|
$findKeywords = function (array $keywords, int $syntaxType) use (&$i): void
|
|
|
|
{
|
|
|
|
foreach ($keywords as $k)
|
|
|
|
{
|
|
|
|
$klen = strlen($k);
|
|
|
|
$nextCharOffset = $i + $klen;
|
|
|
|
$isEndOfLine = $nextCharOffset >= $this->rsize;
|
2021-04-09 13:52:01 -04:00
|
|
|
$nextChar = ($isEndOfLine) ? RawKeyCode::NULL : $this->render[$nextCharOffset];
|
2019-11-05 12:28:10 -05:00
|
|
|
|
|
|
|
if (substr($this->render, $i, $klen) === $k && is_separator($nextChar))
|
|
|
|
{
|
|
|
|
array_replace_range($this->hl, $i, $klen, $syntaxType);
|
|
|
|
$i += $klen - 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
$findKeywords($keywords1, Highlight::KEYWORD1);
|
|
|
|
$findKeywords($keywords2, Highlight::KEYWORD2);
|
2019-10-25 14:49:34 -04:00
|
|
|
}
|
|
|
|
|
2019-10-24 16:57:27 -04:00
|
|
|
$prevSep = is_separator($char);
|
|
|
|
$i++;
|
|
|
|
}
|
2019-10-25 16:36:03 -04:00
|
|
|
|
|
|
|
$changed = $this->hlOpenComment !== $inComment;
|
|
|
|
$this->hlOpenComment = $inComment;
|
|
|
|
if ($changed && $this->idx + 1 < $this->parent->numRows)
|
|
|
|
{
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreStart
|
2021-03-17 13:14:16 -04:00
|
|
|
$this->parent->rows[$this->idx + 1]->highlight();
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreEnd
|
2019-10-25 16:36:03 -04:00
|
|
|
}
|
2019-10-24 16:57:27 -04:00
|
|
|
}
|
2019-10-29 17:02:03 -04:00
|
|
|
|
2021-03-17 08:52:17 -04:00
|
|
|
protected function highlightPHP(): void
|
2019-10-29 17:02:03 -04:00
|
|
|
{
|
2019-11-05 16:56:18 -05:00
|
|
|
$rowNum = $this->idx + 1;
|
|
|
|
|
2019-11-15 16:19:34 -05:00
|
|
|
$hasRowTokens = array_key_exists($rowNum, $this->parent->tokens);
|
2019-11-14 11:12:32 -05:00
|
|
|
|
|
|
|
if ( ! (
|
2019-11-15 16:19:34 -05:00
|
|
|
$hasRowTokens &&
|
2019-11-14 11:12:32 -05:00
|
|
|
$this->idx < $this->parent->numRows
|
|
|
|
))
|
2019-11-05 12:56:12 -05:00
|
|
|
{
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreStart
|
2019-11-05 12:56:12 -05:00
|
|
|
return;
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreEnd
|
2019-11-05 12:56:12 -05:00
|
|
|
}
|
2019-11-05 13:21:37 -05:00
|
|
|
|
2019-11-15 16:19:34 -05:00
|
|
|
$tokens = $this->parent->tokens[$rowNum];
|
2019-10-29 17:02:03 -04:00
|
|
|
|
2019-11-05 16:56:18 -05:00
|
|
|
$inComment = ($this->idx > 0 && $this->parent->rows[$this->idx - 1]->hlOpenComment);
|
2019-10-30 14:21:10 -04:00
|
|
|
|
2019-10-29 17:02:03 -04:00
|
|
|
// Keep track of where you are in the line, so that
|
|
|
|
// multiples of the same tokens can be effectively matched
|
|
|
|
$offset = 0;
|
|
|
|
|
|
|
|
foreach ($tokens as $token)
|
|
|
|
{
|
2019-10-30 14:21:10 -04:00
|
|
|
if ($offset >= $this->rsize)
|
|
|
|
{
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreStart
|
2019-10-30 14:21:10 -04:00
|
|
|
break;
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreEnd
|
2019-10-30 14:21:10 -04:00
|
|
|
}
|
|
|
|
|
2019-11-06 13:57:19 -05:00
|
|
|
// A multi-line comment can end in the middle of a line...
|
2019-11-08 12:02:00 -05:00
|
|
|
if ($inComment)
|
2019-10-30 14:21:10 -04:00
|
|
|
{
|
2019-11-08 12:02:00 -05:00
|
|
|
// Try looking for the end of the comment first
|
|
|
|
$commentEnd = strpos($this->render, '*/');
|
|
|
|
if ($commentEnd !== FALSE)
|
2019-11-06 13:57:19 -05:00
|
|
|
{
|
|
|
|
$inComment = FALSE;
|
2019-11-08 13:28:24 -05:00
|
|
|
array_replace_range($this->hl, 0, $commentEnd + 2, Highlight::ML_COMMENT);
|
2019-11-14 17:11:10 -05:00
|
|
|
$offset = $commentEnd;
|
2019-11-08 12:02:00 -05:00
|
|
|
continue;
|
2019-11-05 16:56:18 -05:00
|
|
|
}
|
|
|
|
|
2019-11-08 12:02:00 -05:00
|
|
|
// Otherwise, just set the whole row
|
|
|
|
$this->hl = array_fill(0, $this->rsize, Highlight::ML_COMMENT);
|
2019-11-05 16:56:18 -05:00
|
|
|
$this->hl[$offset] = Highlight::ML_COMMENT;
|
2019-11-08 12:02:00 -05:00
|
|
|
break;
|
2019-11-05 16:56:18 -05:00
|
|
|
}
|
2019-11-06 13:57:19 -05:00
|
|
|
|
2021-03-03 13:14:44 -05:00
|
|
|
$char = $token['char']; // ?? '';
|
2019-11-06 13:57:19 -05:00
|
|
|
$charLen = strlen($char);
|
|
|
|
if ($charLen === 0 || $offset >= $this->rsize)
|
|
|
|
{
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreStart
|
2019-11-06 13:57:19 -05:00
|
|
|
continue;
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreEnd
|
2019-11-06 13:57:19 -05:00
|
|
|
}
|
|
|
|
$charStart = strpos($this->render, $char, $offset);
|
|
|
|
if ($charStart === FALSE)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2019-11-08 12:02:00 -05:00
|
|
|
$charEnd = $charStart + $charLen;
|
2019-11-06 14:48:21 -05:00
|
|
|
|
2019-11-06 13:57:19 -05:00
|
|
|
// Start of multiline comment/single line comment
|
2019-11-05 16:56:18 -05:00
|
|
|
if (in_array($token['type'], [T_DOC_COMMENT, T_COMMENT], TRUE))
|
|
|
|
{
|
|
|
|
// Single line comments
|
2021-03-03 11:50:29 -05:00
|
|
|
if (str_contains($char, '//') || str_contains($char, '#'))
|
2019-11-05 16:56:18 -05:00
|
|
|
{
|
2019-11-08 12:02:00 -05:00
|
|
|
array_replace_range($this->hl, $charStart, $charLen, Highlight::COMMENT);
|
2019-11-05 16:56:18 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start of multi-line comment
|
|
|
|
$start = strpos($this->render, '/*', $offset);
|
2019-11-08 13:28:24 -05:00
|
|
|
$end = strpos($this->render, '*/', $offset);
|
2019-11-14 11:12:32 -05:00
|
|
|
$hasStart = $start !== FALSE;
|
|
|
|
$hasEnd = $end !== FALSE;
|
|
|
|
|
|
|
|
if ($hasStart)
|
2019-11-08 13:28:24 -05:00
|
|
|
{
|
2019-11-14 11:12:32 -05:00
|
|
|
if ($hasEnd)
|
|
|
|
{
|
|
|
|
$len = $end - $start + 2;
|
|
|
|
array_replace_range($this->hl, $start, $len, Highlight::ML_COMMENT);
|
|
|
|
$inComment = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$inComment = TRUE;
|
|
|
|
array_replace_range($this->hl, $start, $charLen - $offset, Highlight::ML_COMMENT);
|
|
|
|
$offset = $start + $charLen - $offset;
|
|
|
|
}
|
2019-11-08 12:02:00 -05:00
|
|
|
}
|
2019-11-05 16:56:18 -05:00
|
|
|
|
|
|
|
if ($inComment)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2019-10-29 17:24:04 -04:00
|
|
|
}
|
|
|
|
|
2021-03-10 11:10:52 -05:00
|
|
|
$tokenHighlight = Highlight::fromPHPToken($token['type']);
|
|
|
|
$charHighlight = Highlight::fromPHPChar(trim($token['char']));
|
2019-11-06 13:57:19 -05:00
|
|
|
|
2021-03-03 16:35:58 -05:00
|
|
|
$hl = match(true) {
|
|
|
|
// Matches a predefined PHP token
|
|
|
|
$token['type'] !== self::T_RAW && $tokenHighlight !== Highlight::NORMAL
|
2021-03-17 08:52:17 -04:00
|
|
|
=> $tokenHighlight,
|
2021-03-03 16:35:58 -05:00
|
|
|
|
|
|
|
// Matches a specific syntax character
|
|
|
|
$charHighlight !== Highlight::NORMAL => $charHighlight,
|
|
|
|
|
|
|
|
// Types/identifiers/keywords that don't have their own token, but are
|
|
|
|
// defined as keywords
|
2021-03-17 08:52:17 -04:00
|
|
|
in_array($token['char'], $this->parent->fileType->syntax->keywords2, TRUE)
|
2021-03-03 16:35:58 -05:00
|
|
|
=> Highlight::KEYWORD2,
|
2019-11-05 16:56:18 -05:00
|
|
|
|
2021-03-03 16:35:58 -05:00
|
|
|
default => Highlight::NORMAL,
|
|
|
|
};
|
|
|
|
|
|
|
|
if ($hl !== Highlight::NORMAL)
|
2019-11-05 16:56:18 -05:00
|
|
|
{
|
2019-11-08 12:02:00 -05:00
|
|
|
array_replace_range($this->hl, $charStart, $charLen, $hl);
|
|
|
|
$offset = $charEnd;
|
2019-11-05 16:56:18 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$changed = $this->hlOpenComment !== $inComment;
|
|
|
|
$this->hlOpenComment = $inComment;
|
2021-03-03 16:35:58 -05:00
|
|
|
if ($changed && ($this->idx + 1) < $this->parent->numRows)
|
2019-11-05 16:56:18 -05:00
|
|
|
{
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreStart
|
2021-03-17 13:14:16 -04:00
|
|
|
$this->parent->rows[$this->idx + 1]->highlight();
|
2019-12-04 10:54:15 -05:00
|
|
|
// @codeCoverageIgnoreEnd
|
2019-10-29 17:02:03 -04:00
|
|
|
}
|
|
|
|
}
|
2019-10-24 16:57:27 -04:00
|
|
|
}
|