fileType = FileType::from($this->filename); } public function __get(string $name): ?int { if ($name === 'numRows') { return count($this->rows); } return NULL; } public static function default(): self { return new self(); } protected function rowsToString(): string { $lines = array_map(fn (Row $row) => (string)$row, $this->rows); return implode('', $lines); } public static function open(string $filename): ?self { $handle = fopen($filename, 'rb'); if ($handle === FALSE) { return NULL; } $self = new self(filename: $filename); while (($line = fgets($handle)) !== FALSE) { // Remove line endings when reading the file $self->insertRow($self->numRows, rtrim($line), FALSE); } fclose($handle); $self->selectSyntaxHighlight(); return $self; } public function save(): int|false { $contents = $this->rowsToString(); $res = file_put_contents($this->filename, $contents); if ($res === strlen($contents)) { $this->dirty = FALSE; } return $res; } public function insertChar(Point $at, string $c): void { } public function insertRow(int $at, string $s, bool $updateSyntax = TRUE): void { if ($at > $this->numRows) { return; } $row = Row::new($this, $s, $at); if ($at === $this->numRows) { $this->rows[] = $row; } else { $this->rows = [ ...array_slice($this->rows, 0, $at), $row, ...array_slice($this->rows, $at), ]; // Update indexes of each row so that correct highlighting is done for ($idx = $at; $idx < $this->numRows; $idx++) { $this->rows[$idx]->idx = $idx; } } ksort($this->rows); $this->rows[$at]->update(); $this->dirty = true; // Re-tokenize the file if ($updateSyntax) { $this->refreshPHPSyntax(); } } public function isDirty(): bool { return $this->dirty; } public function deleteChar(Point $at): void { } private function insertNewline(Point $at): void { } public function selectSyntaxHighlight(): void { if (empty($this->filename)) { return; } if ($this->fileType->name === 'PHP') { $this->tokens = PHP8::getFileTokens($this->filename); } $this->refreshSyntax(); } public function refreshSyntax(): void { // Update the syntax highlighting for all the rows of the file array_walk($this->rows, static fn (Row $row) => $row->update()); } private function refreshPHPSyntax(): void { if ($this->fileType->name !== 'PHP') { return; } $this->tokens = PHP8::getTokens($this->rowsToString()); $this->refreshSyntax(); } }