Complete tutorial
This commit is contained in:
parent
4df0644bc2
commit
ca9ec17d49
@ -3,6 +3,7 @@
|
|||||||
namespace Kilo;
|
namespace Kilo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* // Don't highlight this!
|
||||||
* @property-read int numRows
|
* @property-read int numRows
|
||||||
*/
|
*/
|
||||||
class Editor {
|
class Editor {
|
||||||
@ -21,7 +22,7 @@ class Editor {
|
|||||||
/**
|
/**
|
||||||
* Array of Row objects
|
* Array of Row objects
|
||||||
*/
|
*/
|
||||||
protected array $rows = [];
|
public array $rows = [];
|
||||||
|
|
||||||
public int $dirty = 0;
|
public int $dirty = 0;
|
||||||
protected string $filename = '';
|
protected string $filename = '';
|
||||||
@ -179,7 +180,13 @@ class Editor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = Row::new($this, $s);
|
$row = Row::new($this, $s, $at);
|
||||||
|
// Update other row indices
|
||||||
|
for ($i = $at + 1; $i <= $this->numRows; $i++)
|
||||||
|
{
|
||||||
|
$this->rows[$i]->idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($at === $this->numRows)
|
if ($at === $this->numRows)
|
||||||
{
|
{
|
||||||
@ -211,6 +218,10 @@ class Editor {
|
|||||||
|
|
||||||
// Re-index the array of rows
|
// Re-index the array of rows
|
||||||
$this->rows = array_values($this->rows);
|
$this->rows = array_values($this->rows);
|
||||||
|
for ($i = $at; $i < $this->numRows; $i++)
|
||||||
|
{
|
||||||
|
$this->rows[$i]->idx--;
|
||||||
|
}
|
||||||
|
|
||||||
$this->dirty++;
|
$this->dirty++;
|
||||||
}
|
}
|
||||||
@ -388,6 +399,12 @@ class Editor {
|
|||||||
{
|
{
|
||||||
$direction = 1;
|
$direction = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty($query))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$current = $lastMatch;
|
$current = $lastMatch;
|
||||||
|
|
||||||
for ($i = 0; $i < $this->numRows; $i++)
|
for ($i = 0; $i < $this->numRows; $i++)
|
||||||
@ -497,7 +514,7 @@ class Editor {
|
|||||||
$this->ab .= '~';
|
$this->ab .= '~';
|
||||||
$padding--;
|
$padding--;
|
||||||
}
|
}
|
||||||
for (; $padding >= 0; $padding--)
|
for ($i = 0; $i < $padding; $i++)
|
||||||
{
|
{
|
||||||
$this->ab .= ' ';
|
$this->ab .= ' ';
|
||||||
}
|
}
|
||||||
@ -546,8 +563,8 @@ class Editor {
|
|||||||
{
|
{
|
||||||
if ($currentColor !== -1)
|
if ($currentColor !== -1)
|
||||||
{
|
{
|
||||||
$this->ab .= "\x1b[39m"; // Reset foreground color
|
|
||||||
$this->ab .= "\x1b[0m"; // Reset background color
|
$this->ab .= "\x1b[0m"; // Reset background color
|
||||||
|
$this->ab .= "\x1b[39m"; // Reset foreground color
|
||||||
$currentColor = -1;
|
$currentColor = -1;
|
||||||
}
|
}
|
||||||
$this->ab .= $c[$i];
|
$this->ab .= $c[$i];
|
||||||
@ -565,8 +582,8 @@ class Editor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ab .= "\x1b[39m";
|
|
||||||
$this->ab .= "\x1b[0m";
|
$this->ab .= "\x1b[0m";
|
||||||
|
$this->ab .= "\x1b[39m";
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ab .= "\x1b[K"; // Clear the current line
|
$this->ab .= "\x1b[K"; // Clear the current line
|
||||||
|
@ -5,9 +5,10 @@ namespace Kilo;
|
|||||||
class Highlight {
|
class Highlight {
|
||||||
public const NORMAL = 0;
|
public const NORMAL = 0;
|
||||||
public const COMMENT = 1;
|
public const COMMENT = 1;
|
||||||
public const KEYWORD1 = 2;
|
public const ML_COMMENT = 2;
|
||||||
public const KEYWORD2 = 3;
|
public const KEYWORD1 = 3;
|
||||||
public const STRING = 4;
|
public const KEYWORD2 = 4;
|
||||||
public const NUMBER = 5;
|
public const STRING = 5;
|
||||||
public const MATCH = 6;
|
public const NUMBER = 6;
|
||||||
|
public const MATCH = 7;
|
||||||
}
|
}
|
57
src/Row.php
57
src/Row.php
@ -12,16 +12,20 @@ class Row {
|
|||||||
public string $chars = '';
|
public string $chars = '';
|
||||||
public string $render = '';
|
public string $render = '';
|
||||||
|
|
||||||
// This feels dirty...
|
|
||||||
private Editor $parent;
|
|
||||||
|
|
||||||
public array $hl = [];
|
public array $hl = [];
|
||||||
|
|
||||||
public static function new(Editor $parent, string $chars): self
|
public int $idx;
|
||||||
|
|
||||||
|
// This feels dirty...
|
||||||
|
private Editor $parent;
|
||||||
|
private bool $hlOpenComment = FALSE;
|
||||||
|
|
||||||
|
public static function new(Editor $parent, string $chars, int $idx): self
|
||||||
{
|
{
|
||||||
$self = new self();
|
$self = new self();
|
||||||
$self->chars = $chars;
|
$self->chars = $chars;
|
||||||
$self->parent = $parent;
|
$self->parent = $parent;
|
||||||
|
$self->idx = $idx;
|
||||||
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
@ -118,9 +122,16 @@ class Row {
|
|||||||
$keywords2 = $this->parent->syntax->keywords2;
|
$keywords2 = $this->parent->syntax->keywords2;
|
||||||
|
|
||||||
$scs = $this->parent->syntax->singleLineCommentStart;
|
$scs = $this->parent->syntax->singleLineCommentStart;
|
||||||
|
$mcs = $this->parent->syntax->multiLineCommentStart;
|
||||||
|
$mce = $this->parent->syntax->multiLineCommentEnd;
|
||||||
|
|
||||||
|
$scsLen = strlen($scs);
|
||||||
|
$mcsLen = strlen($mcs);
|
||||||
|
$mceLen = strlen($mce);
|
||||||
|
|
||||||
$prevSep = TRUE;
|
$prevSep = TRUE;
|
||||||
$inString = '';
|
$inString = '';
|
||||||
|
$inComment = ($this->idx > 0 && $this->parent->rows[$this->idx - 1]->hlOpenComment);
|
||||||
|
|
||||||
$i = 0;
|
$i = 0;
|
||||||
|
|
||||||
@ -135,12 +146,41 @@ class Row {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Single-line comments
|
// Single-line comments
|
||||||
if ($scs !== '' && empty($inString) && substr($this->render, $i, strlen($scs)) === $scs)// strncmp($char, $scs, strlen($scs)) === 0)
|
if ($scsLen > 0 && $inString === '' && $inComment === FALSE
|
||||||
|
&& substr($this->render, $i, $scsLen) === $scs)
|
||||||
{
|
{
|
||||||
array_replace_range($this->hl, $i, $this->rsize - $i, Highlight::COMMENT);
|
array_replace_range($this->hl, $i, $this->rsize - $i, Highlight::COMMENT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// String/Char literals
|
// String/Char literals
|
||||||
if ($this->parent->syntax->flags & Syntax::HIGHLIGHT_STRINGS)
|
if ($this->parent->syntax->flags & Syntax::HIGHLIGHT_STRINGS)
|
||||||
{
|
{
|
||||||
@ -226,5 +266,12 @@ class Row {
|
|||||||
$prevSep = is_separator($char);
|
$prevSep = is_separator($char);
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$changed = $this->hlOpenComment !== $inComment;
|
||||||
|
$this->hlOpenComment = $inComment;
|
||||||
|
if ($changed && $this->idx + 1 < $this->parent->numRows)
|
||||||
|
{
|
||||||
|
$this->parent->rows[$this->idx + 1]->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,17 @@ class Syntax {
|
|||||||
|
|
||||||
public string $filetype = '';
|
public string $filetype = '';
|
||||||
public array $filematch = [];
|
public array $filematch = [];
|
||||||
|
|
||||||
public string $singleLineCommentStart = '//';
|
public string $singleLineCommentStart = '//';
|
||||||
|
public string $multiLineCommentStart = '/*';
|
||||||
|
public string $multiLineCommentEnd = '*/';
|
||||||
|
|
||||||
public array $keywords1 = [];
|
public array $keywords1 = [];
|
||||||
public array $keywords2 = [];
|
public array $keywords2 = [];
|
||||||
|
|
||||||
public int $flags = 0;
|
public int $flags = 0;
|
||||||
|
|
||||||
public static function new(string $name, array $extList, array $keywords1, array $keywords2, string $slcs, int $flags): self
|
public static function new(string $name, array $extList, array $keywords1, array $keywords2, string $slcs, string $mcs, string $mce, int $flags): self
|
||||||
{
|
{
|
||||||
$self = new self();
|
$self = new self();
|
||||||
|
|
||||||
@ -26,6 +29,8 @@ class Syntax {
|
|||||||
$self->keywords2 = $keywords2;
|
$self->keywords2 = $keywords2;
|
||||||
|
|
||||||
$self->singleLineCommentStart = $slcs;
|
$self->singleLineCommentStart = $slcs;
|
||||||
|
$self->multiLineCommentStart = $mcs;
|
||||||
|
$self->multiLineCommentEnd = $mce;
|
||||||
|
|
||||||
$self->flags = $flags;
|
$self->flags = $flags;
|
||||||
|
|
||||||
|
@ -283,11 +283,12 @@ function syntax_to_color(int $hl): int
|
|||||||
{
|
{
|
||||||
$map = [
|
$map = [
|
||||||
Highlight::COMMENT => 36, // Foreground Cyan,
|
Highlight::COMMENT => 36, // Foreground Cyan,
|
||||||
|
Highlight::ML_COMMENT => 90, // Foreground Bright Black
|
||||||
Highlight::KEYWORD1 => 33, // Foreground Yellow
|
Highlight::KEYWORD1 => 33, // Foreground Yellow
|
||||||
Highlight::KEYWORD2 => 32, // Foreground Green
|
Highlight::KEYWORD2 => 32, // Foreground Green
|
||||||
Highlight::STRING => 35, // Foreground Magenta
|
Highlight::STRING => 35, // Foreground Magenta
|
||||||
Highlight::NUMBER => 31, // Foreground Red
|
Highlight::NUMBER => 31, // Foreground Red
|
||||||
Highlight::MATCH => 34, // Foreground Blue
|
Highlight::MATCH => 7, // Reverse!
|
||||||
];
|
];
|
||||||
|
|
||||||
return (array_key_exists($hl, $map))
|
return (array_key_exists($hl, $map))
|
||||||
|
10
src/hldb.php
10
src/hldb.php
@ -21,6 +21,8 @@ function get_hldb(): array
|
|||||||
'#ifdef', 'float', '#error', '#undef', 'long', 'char', 'int', 'void', '#if',
|
'#ifdef', 'float', '#error', '#undef', 'long', 'char', 'int', 'void', '#if',
|
||||||
],
|
],
|
||||||
'//',
|
'//',
|
||||||
|
'/*',
|
||||||
|
'*/',
|
||||||
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
||||||
),
|
),
|
||||||
Syntax::new(
|
Syntax::new(
|
||||||
@ -29,6 +31,8 @@ function get_hldb(): array
|
|||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
'',
|
'',
|
||||||
|
'/*',
|
||||||
|
'*/',
|
||||||
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
||||||
),
|
),
|
||||||
Syntax::new(
|
Syntax::new(
|
||||||
@ -75,6 +79,8 @@ function get_hldb(): array
|
|||||||
'=>', 'Number', 'String', 'Object', 'Math', 'JSON', 'Boolean',
|
'=>', 'Number', 'String', 'Object', 'Math', 'JSON', 'Boolean',
|
||||||
],
|
],
|
||||||
'//',
|
'//',
|
||||||
|
'/*',
|
||||||
|
'*/',
|
||||||
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
||||||
),
|
),
|
||||||
Syntax::new(
|
Syntax::new(
|
||||||
@ -97,6 +103,8 @@ function get_hldb(): array
|
|||||||
'void', 'iterable', 'object', 'strict_types'
|
'void', 'iterable', 'object', 'strict_types'
|
||||||
],
|
],
|
||||||
'//',
|
'//',
|
||||||
|
'/*',
|
||||||
|
'*/',
|
||||||
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
||||||
),
|
),
|
||||||
Syntax::new(
|
Syntax::new(
|
||||||
@ -168,6 +176,8 @@ function get_hldb(): array
|
|||||||
'u8',
|
'u8',
|
||||||
],
|
],
|
||||||
'//',
|
'//',
|
||||||
|
'/*',
|
||||||
|
'*/',
|
||||||
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
Loading…
Reference in New Issue
Block a user