From 5566441dc3f1aae3e5e353df3480906ae348c46a Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Fri, 25 Oct 2019 10:28:15 -0400 Subject: [PATCH] Complete step 164 --- kilo | 1 + src/Editor.php | 93 ++++++++++++++++++++++++++------------------------ src/Row.php | 77 +++++++++++++++++++++++++++++++++-------- src/hldb.php | 21 ++++++++++++ 4 files changed, 132 insertions(+), 60 deletions(-) create mode 100644 src/hldb.php diff --git a/kilo b/kilo index 8ab5507..d5eda09 100755 --- a/kilo +++ b/kilo @@ -12,6 +12,7 @@ define('KILO_QUIT_TIMES', 3); // Set up autoloading require_once __DIR__ . '/src/functions.php'; +require_once __DIR__ . '/src/hldb.php'; spl_autoload_register(static function ($class) { $parts = explode('\\', $class); $file = __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . $parts[1] . '.php'; diff --git a/src/Editor.php b/src/Editor.php index 4a1880f..e547b39 100644 --- a/src/Editor.php +++ b/src/Editor.php @@ -23,11 +23,13 @@ class Editor { */ protected array $rows = []; - protected int $dirty = 0; + public int $dirty = 0; protected string $filename = ''; protected string $statusMsg = ''; protected int $statusMsgTime; + public ?Syntax $syntax; + public static function new(): Editor { return new self(); @@ -97,6 +99,42 @@ class Editor { } } + protected function selectSyntaxHighlight(): void + { + $this->syntax = NULL; + if (empty($this->filename)) + { + return; + } + + // In PHP, `strchr` and `strstr` are the same function + $ext = (string)strstr($this->filename, '.'); + + foreach (get_hldb() as $syntax) + { + $i = 0; + while ($syntax->filematch[$i]) + { + $is_ext = ($syntax->filematch[$i][0] === '.'); + if ( + ($is_ext && ( ! strcmp($ext, $syntax->filematch[$i]))) || + (( ! $is_ext) && strpos($this->filename, $syntax->filematch{$i}) !== FALSE) + ) { + $this->syntax = $syntax; + + for ($i = 0; $i < $this->numRows; $i++) + { + $this->rows[$i]->update(); + } + + return; + } + + $i++; + } + } + } + // ------------------------------------------------------------------------ // ! Row Operations // ------------------------------------------------------------------------ @@ -143,7 +181,7 @@ class Editor { return; } - $row = Row::new($s); + $row = Row::new($this, $s); if ($at === $this->numRows) { @@ -179,38 +217,6 @@ class Editor { $this->dirty++; } - protected function rowInsertChar(Row $row, int $at, string $c): void - { - if ($at < 0 || $at > $row->size) - { - $at = $row->size; - } - - // Safely insert into arbitrary position in the existing string - $row->chars = substr($row->chars, 0, $at) . $c . substr($row->chars, $at); - $row->update(); - $this->dirty++; - } - - protected function rowAppendString(Row $row, string $s): void - { - $row->chars .= $s; - $row->update(); - $this->dirty++; - } - - protected function rowDeleteChar(Row $row, int $at): void - { - if ($at < 0 || $at >= $row->size) - { - return; - } - - $row->chars = substr_replace($row->chars, '', $at, 1); - $row->update(); - $this->dirty++; - } - // ------------------------------------------------------------------------ // ! Editor Operations // ------------------------------------------------------------------------ @@ -221,7 +227,7 @@ class Editor { { $this->insertRow($this->numRows, ''); } - $this->rowInsertChar($this->rows[$this->cursorY], $this->cursorX, $c); + $this->rows[$this->cursorY]->insertChar($this->cursorX, $c); $this->cursorX++; } @@ -257,13 +263,13 @@ class Editor { $row = $this->rows[$this->cursorY]; if ($this->cursorX > 0) { - $this->rowDeleteChar($row, $this->cursorX - 1); + $row->deleteChar($this->cursorX - 1); $this->cursorX--; } else { $this->cursorX = $this->rows[$this->cursorY - 1]->size; - $this->rowAppendString($this->rows[$this->cursorY -1], $row->chars); + $this->rows[$this->cursorY -1]->appendString($row->chars); $this->deleteRow($this->cursorY); $this->cursorY--; } @@ -289,12 +295,7 @@ class Editor { // Copy filename for display $this->filename = $filename; - // Determine the full path to the file - /* $baseFile = basename($filename); - $basePath = str_replace($baseFile, '', $filename); - $path = (is_dir($basePath)) ? $basePath : getcwd(); - - $fullname = $path . '/' . $baseFile; */ + $this->selectSyntaxHighlight(); // #TODO gracefully handle issues with loading a file $handle = fopen($filename, 'rb'); @@ -302,7 +303,7 @@ class Editor { { write_stdout("\x1b[2J"); // Clear the screen write_stdout("\x1b[H"); // Reposition cursor to top-left - disableRawMode(); + disable_raw_mode(); print_r(error_get_last()); die(); } @@ -330,6 +331,7 @@ class Editor { } $this->filename = $newFilename; + $this->selectSyntaxHighlight(); } $contents = $this->rowsToString(); @@ -565,9 +567,10 @@ class Editor { $this->ab .= "\x1b[7m"; $statusFilename = $this->filename !== '' ? $this->filename : '[No Name]'; + $syntaxType = ($this->syntax !== NULL) ? $this->syntax->filetype : 'no ft'; $isDirty = ($this->dirty > 0) ? '(modified)' : ''; $status = sprintf('%.20s - %d lines %s', $statusFilename, $this->numRows, $isDirty); - $rstatus = sprintf('%d/%d', $this->cursorY + 1, $this->numRows); + $rstatus = sprintf('%s | %d/%d', $syntaxType, $this->cursorY + 1, $this->numRows); $len = strlen($status); $rlen = strlen($rstatus); if ($len > $this->screenCols) diff --git a/src/Row.php b/src/Row.php index 307baf1..faf987e 100644 --- a/src/Row.php +++ b/src/Row.php @@ -12,17 +12,21 @@ class Row { public string $chars = ''; public string $render = ''; + // This feels dirty... + private Editor $parent; + public array $hl = []; - public static function new(string $chars): self + public static function new(Editor $parent, string $chars): self { - return new self($chars); + $self = new self(); + $self->chars = $chars; + $self->parent = $parent; + + return $self; } - private function __construct($chars) - { - $this->chars = $chars; - } + private function __construct() {} public function __get(string $name) { @@ -44,6 +48,41 @@ class Row { return $this->chars . "\n"; } + public function insertChar(int $at, string $c): void + { + if ($at < 0 || $at > $this->size) + { + $at = $this->size; + } + + // Safely insert into arbitrary position in the existing string + $this->chars = substr($this->chars, 0, $at) . $c . substr($this->chars, $at); + $this->update(); + + $this->parent->dirty++; + } + + public function appendString(string $s): void + { + $this->chars .= $s; + $this->update(); + + $this->parent->dirty++; + } + + public function deleteChar(int $at): void + { + if ($at < 0 || $at >= $this->size) + { + return; + } + + $this->chars = substr_replace($this->chars, '', $at, 1); + $this->update(); + + $this->parent->dirty++; + } + public function update(): void { $idx = 0; @@ -84,16 +123,24 @@ class Row { $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)) - ) + if ($this->parent->syntax === NULL) { - $this->hl[$i] = Highlight::NUMBER; - $i++; - $prevSep = FALSE; - continue; + return; + } + + if ($this->parent->syntax->flags & Syntax::HIGHLIGHT_NUMBERS) + { + // 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); diff --git a/src/hldb.php b/src/hldb.php new file mode 100644 index 0000000..138c519 --- /dev/null +++ b/src/hldb.php @@ -0,0 +1,21 @@ +