From ca9ec17d493edd7ce2059444d9313080439e9b0f Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Fri, 25 Oct 2019 16:36:03 -0400 Subject: [PATCH] Complete tutorial --- src/Editor.php | 27 +++++++++++++++++----- src/Highlight.php | 11 ++++----- src/Row.php | 57 ++++++++++++++++++++++++++++++++++++++++++----- src/Syntax.php | 7 +++++- src/functions.php | 3 ++- src/hldb.php | 10 +++++++++ 6 files changed, 98 insertions(+), 17 deletions(-) diff --git a/src/Editor.php b/src/Editor.php index eb9cae0..9a3bbba 100644 --- a/src/Editor.php +++ b/src/Editor.php @@ -3,6 +3,7 @@ namespace Kilo; /** + * // Don't highlight this! * @property-read int numRows */ class Editor { @@ -21,7 +22,7 @@ class Editor { /** * Array of Row objects */ - protected array $rows = []; + public array $rows = []; public int $dirty = 0; protected string $filename = ''; @@ -179,7 +180,13 @@ class Editor { 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) { @@ -211,6 +218,10 @@ class Editor { // Re-index the array of rows $this->rows = array_values($this->rows); + for ($i = $at; $i < $this->numRows; $i++) + { + $this->rows[$i]->idx--; + } $this->dirty++; } @@ -388,6 +399,12 @@ class Editor { { $direction = 1; } + + if (empty($query)) + { + return; + } + $current = $lastMatch; for ($i = 0; $i < $this->numRows; $i++) @@ -497,7 +514,7 @@ class Editor { $this->ab .= '~'; $padding--; } - for (; $padding >= 0; $padding--) + for ($i = 0; $i < $padding; $i++) { $this->ab .= ' '; } @@ -546,8 +563,8 @@ class Editor { { if ($currentColor !== -1) { - $this->ab .= "\x1b[39m"; // Reset foreground color $this->ab .= "\x1b[0m"; // Reset background color + $this->ab .= "\x1b[39m"; // Reset foreground color $currentColor = -1; } $this->ab .= $c[$i]; @@ -565,8 +582,8 @@ class Editor { } } - $this->ab .= "\x1b[39m"; $this->ab .= "\x1b[0m"; + $this->ab .= "\x1b[39m"; } $this->ab .= "\x1b[K"; // Clear the current line diff --git a/src/Highlight.php b/src/Highlight.php index a32e441..afed987 100644 --- a/src/Highlight.php +++ b/src/Highlight.php @@ -5,9 +5,10 @@ namespace Kilo; class Highlight { public const NORMAL = 0; public const COMMENT = 1; - public const KEYWORD1 = 2; - public const KEYWORD2 = 3; - public const STRING = 4; - public const NUMBER = 5; - public const MATCH = 6; + public const ML_COMMENT = 2; + public const KEYWORD1 = 3; + public const KEYWORD2 = 4; + public const STRING = 5; + public const NUMBER = 6; + public const MATCH = 7; } \ No newline at end of file diff --git a/src/Row.php b/src/Row.php index bdbe3c6..7734e33 100644 --- a/src/Row.php +++ b/src/Row.php @@ -12,16 +12,20 @@ class Row { public string $chars = ''; public string $render = ''; - // This feels dirty... - private Editor $parent; - 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->chars = $chars; $self->parent = $parent; + $self->idx = $idx; return $self; } @@ -118,9 +122,16 @@ class Row { $keywords2 = $this->parent->syntax->keywords2; $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; $inString = ''; + $inComment = ($this->idx > 0 && $this->parent->rows[$this->idx - 1]->hlOpenComment); $i = 0; @@ -135,12 +146,41 @@ class Row { } // 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); 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 if ($this->parent->syntax->flags & Syntax::HIGHLIGHT_STRINGS) { @@ -226,5 +266,12 @@ class Row { $prevSep = is_separator($char); $i++; } + + $changed = $this->hlOpenComment !== $inComment; + $this->hlOpenComment = $inComment; + if ($changed && $this->idx + 1 < $this->parent->numRows) + { + $this->parent->rows[$this->idx + 1]->update(); + } } } diff --git a/src/Syntax.php b/src/Syntax.php index 8e0f471..b4100d5 100644 --- a/src/Syntax.php +++ b/src/Syntax.php @@ -8,14 +8,17 @@ class Syntax { public string $filetype = ''; public array $filematch = []; + public string $singleLineCommentStart = '//'; + public string $multiLineCommentStart = '/*'; + public string $multiLineCommentEnd = '*/'; public array $keywords1 = []; public array $keywords2 = []; 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(); @@ -26,6 +29,8 @@ class Syntax { $self->keywords2 = $keywords2; $self->singleLineCommentStart = $slcs; + $self->multiLineCommentStart = $mcs; + $self->multiLineCommentEnd = $mce; $self->flags = $flags; diff --git a/src/functions.php b/src/functions.php index 643075a..41719da 100644 --- a/src/functions.php +++ b/src/functions.php @@ -283,11 +283,12 @@ function syntax_to_color(int $hl): int { $map = [ Highlight::COMMENT => 36, // Foreground Cyan, + Highlight::ML_COMMENT => 90, // Foreground Bright Black Highlight::KEYWORD1 => 33, // Foreground Yellow Highlight::KEYWORD2 => 32, // Foreground Green Highlight::STRING => 35, // Foreground Magenta Highlight::NUMBER => 31, // Foreground Red - Highlight::MATCH => 34, // Foreground Blue + Highlight::MATCH => 7, // Reverse! ]; return (array_key_exists($hl, $map)) diff --git a/src/hldb.php b/src/hldb.php index 801559a..cabacf3 100644 --- a/src/hldb.php +++ b/src/hldb.php @@ -21,6 +21,8 @@ function get_hldb(): array '#ifdef', 'float', '#error', '#undef', 'long', 'char', 'int', 'void', '#if', ], '//', + '/*', + '*/', Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS, ), Syntax::new( @@ -29,6 +31,8 @@ function get_hldb(): array [], [], '', + '/*', + '*/', Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS, ), Syntax::new( @@ -75,6 +79,8 @@ function get_hldb(): array '=>', 'Number', 'String', 'Object', 'Math', 'JSON', 'Boolean', ], '//', + '/*', + '*/', Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS, ), Syntax::new( @@ -97,6 +103,8 @@ function get_hldb(): array 'void', 'iterable', 'object', 'strict_types' ], '//', + '/*', + '*/', Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS, ), Syntax::new( @@ -168,6 +176,8 @@ function get_hldb(): array 'u8', ], '//', + '/*', + '*/', Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS, ), ];