Some refactoring
timw4mail/php-kilo/pipeline/head This commit looks good Details

This commit is contained in:
Timothy Warren 2021-03-09 17:22:49 -05:00
parent 5329378b93
commit 99685f3fcb
7 changed files with 2552 additions and 2200 deletions

11
kilo
View File

@ -6,7 +6,7 @@ namespace Aviat\Kilo;
require_once __DIR__ . '/vendor/autoload.php';
// Log notices/errors/warnings to file
set_exception_handler(static function (\Throwable $e) {
set_exception_handler(static function (mixed $e) {
$msg = print_r([
'code' => $e->getCode(),
'message' => $e->getMessage(),
@ -31,7 +31,14 @@ return (static function (int $argc, array $argv): int {
}
// Input Loop
do { $editor->refreshScreen();} while ($editor->processKeypress() !== NULL);
while (true)
{
$editor->refreshScreen();
if ($editor->processKeypress() === NULL)
{
break;
}
}
return 0;
})($argc, $argv);

View File

@ -53,7 +53,7 @@ class ANSI {
*/
public static function color(int $color): string
{
return self::seq('%dm', $color);
return self::escapeSequence('%dm', $color);
}
/**
@ -66,7 +66,7 @@ class ANSI {
*/
public static function rgbColor(int $r, int $g, int $b): string
{
return self::seq('38;2;%d;%d;%dm', $r, $g, $b);
return self::escapeSequence('38;2;%d;%d;%dm', $r, $g, $b);
}
/**
@ -80,7 +80,7 @@ class ANSI {
{
// The terminal has a 1-based coordinate system,
// add one to each to allow 0-based coordinate system input
return self::seq('%d;%dH', $line + 1, $column + 1);
return self::escapeSequence('%d;%dH', $line + 1, $column + 1);
}
/**
@ -91,7 +91,7 @@ class ANSI {
*/
public static function scrollUp(int $lines): string
{
return self::seq('%dS', $lines);
return self::escapeSequence('%dS', $lines);
}
/**
@ -102,7 +102,7 @@ class ANSI {
*/
public static function scrollDown(int $lines): string
{
return self::seq('%dT', $lines);
return self::escapeSequence('%dT', $lines);
}
/**
@ -112,7 +112,7 @@ class ANSI {
* @param mixed ...$args
* @return string
*/
private static function seq(string $pattern, mixed ...$args): string
private static function escapeSequence(string $pattern, mixed ...$args): string
{
return sprintf("\e[{$pattern}", ...$args);
}

View File

@ -18,14 +18,14 @@ class Editor {
private string $outputBuffer = '';
/**
* @var Position The 0-based location of the cursor in the current viewport
* @var Point The 0-based location of the cursor in the current viewport
*/
protected Position $cursor;
protected Point $cursor;
/**
* @var Position The scroll offset of the file in the current viewport
* @var Point The scroll offset of the file in the current viewport
*/
protected Position $offset;
protected Point $offset;
/**
* @var int The rendered cursor position
@ -42,6 +42,11 @@ class Editor {
*/
protected int $screenCols = 0;
/**
* @var int The number of times to confirm you wish to quit
*/
protected int $quitTimes = KILO_QUIT_TIMES;
/**
* Array of Row objects
*/
@ -65,8 +70,8 @@ class Editor {
private function __construct()
{
$this->statusMsgTime = time();
$this->cursor = Position::new();
$this->offset = Position::new();
$this->cursor = Point::new();
$this->offset = Point::new();
[$this->screenRows, $this->screenCols] = Terminal::getWindowSize();
@ -507,10 +512,8 @@ class Editor {
protected function find(): void
{
$savedCx = $this->cursor->x;
$savedCy = $this->cursor->y;
$savedColOff = $this->offset->x;
$savedRowOff = $this->offset->y;
$savedCursor = Point::from($this->cursor);
$savedOffset = Point::from($this->offset);
$query = $this->prompt('Search: %s (Use ESC/Arrows/Enter)', [$this, 'findCallback']);
@ -518,10 +521,8 @@ class Editor {
// restore original cursor and scroll locations
if ($query === '')
{
$this->cursor->x = $savedCx;
$this->cursor->y = $savedCy;
$this->offset->x = $savedColOff;
$this->offset->y = $savedRowOff;
$this->cursor = Point::from($savedCursor);
$this->offset = Point::from($savedOffset);
}
}
@ -564,11 +565,12 @@ class Editor {
{
$filerow = $y + $this->offset->y;
$this->outputBuffer .= ANSI::CLEAR_LINE;
($filerow >= $this->numRows)
? $this->drawPlaceholderRow($y)
: $this->drawRow($filerow);
$this->outputBuffer .= ANSI::CLEAR_LINE;
$this->outputBuffer .= "\r\n";
}
}
@ -851,7 +853,7 @@ class Editor {
case KeyType::END_KEY:
if ($y < $this->numRows)
{
$x = $this->rows[$y]->size - 1;
$x = $this->rows[$y]->size;
}
break;
@ -859,13 +861,13 @@ class Editor {
// Do nothing
}
if ($x > $row->size)
// Snap cursor to the end of a row when moving
// from a longer row to a shorter one
$row = $this->rows[$y];
$rowLen = ($row !== NULL) ? $row->size : 0;
if ($x > $rowLen)
{
$x = $row->size;
}
if ($y > $this->screenRows)
{
$y = $this->screenRows;
$x = $rowLen;
}
$this->cursor->x = $x;
@ -874,8 +876,6 @@ class Editor {
public function processKeypress(): ?string
{
static $quit_times = KILO_QUIT_TIMES;
$c = $this->readKey();
if ($c === KeyCode::NULL || $c === KeyCode::EMPTY)
@ -885,21 +885,13 @@ class Editor {
switch ($c)
{
case KeyCode::CTRL('q'):
return $this->quitAttempt();
case KeyType::ENTER:
$this->insertNewline();
break;
case KeyCode::CTRL('q'):
if ($this->dirty > 0 && $quit_times > 0)
{
$this->setStatusMessage('WARNING!!! File has unsaved changes.' .
'Press Ctrl-Q %d more times to quit.', $quit_times);
$quit_times--;
return '';
}
Terminal::clear();
return NULL;
case KeyCode::CTRL('s'):
$this->save();
break;
@ -938,15 +930,32 @@ class Editor {
break;
}
$quit_times = KILO_QUIT_TIMES;
// Reset quit confirmation timer on different keypress
$this->quitTimes = KILO_QUIT_TIMES;
return $c;
}
protected function quitAttempt(): ?string
{
if ($this->dirty > 0 && $this->quitTimes > 0)
{
$this->setStatusMessage(
'WARNING!!! File has unsaved changes. Press Ctrl-Q %d more times to quit.',
$this->quitTimes
);
$this->quitTimes--;
return KeyCode::CTRL('q');
}
Terminal::clear();
return NULL;
}
protected function refreshSyntax(): void
{
// Update the syntax highlighting for all the rows of the file
array_walk($this->rows, static fn (Row $row) => $row->updateSyntax());
array_walk($this->rows, static fn (Row $row) => $row->update());
}
private function refreshPHPSyntax(): void

33
src/Point.php Normal file
View File

@ -0,0 +1,33 @@
<?php declare(strict_types=1);
namespace Aviat\Kilo;
/**
* A representation of a 2d point
*/
final class Point {
private function __construct(public int $x, public int $y) {}
/**
* Create a new Point from coordinates
*
* @param int $x
* @param int $y
* @return Point
*/
public static function new(int $x = 0, int $y = 0): Point
{
return new Point($x, $y);
}
/**
* Create a new Point from another position
*
* @param Point $pos
* @return Point
*/
public static function from(Point $pos): Point
{
return Point::new($pos->x, $pos->y);
}
}

View File

@ -1,12 +0,0 @@
<?php declare(strict_types=1);
namespace Aviat\Kilo;
class Position {
private function __construct(public int $x, public int $y) {}
public static function new(int $x = 0, int $y = 0): self
{
return new Position($x, $y);
}
}

View File

@ -16,6 +16,10 @@ abstract class Foo implements Ifoo {
protected function doNothing(): void {}
}
class Test {
public function __construct(public string $foo, public string $bar) {}
}
/**
* Docblock comment
*/
@ -116,4 +120,4 @@ TEMPLATE;
<h1><?= $_SERVER['HTTP_HOST'] ?></h1>
</body>
</html>
<?php exit(); ?>
<?php exit(); ?>

File diff suppressed because it is too large Load Diff