Compare commits

...

2 Commits

Author SHA1 Message Date
Timothy Warren 228576ccf1 Fix page down behavior, resolves #1
timw4mail/php-kilo/pipeline/head This commit looks good Details
2021-04-16 12:51:53 -04:00
Timothy Warren 4812d548a7 Work on line numbers
timw4mail/php-kilo/pipeline/head This commit looks good Details
2021-04-15 18:35:03 -04:00
5 changed files with 93 additions and 15 deletions

View File

@ -230,6 +230,10 @@ class Document {
// Add a new row with the contents of the previous row at the point of the split // Add a new row with the contents of the previous row at the point of the split
$this->insertRow($at->y + 1, substr($chars, $at->x)); $this->insertRow($at->y + 1, substr($chars, $at->x));
// Highlight the two changed rows
$row->update();
$this->rows[$at->y + 1]->update();
} }
$this->dirty = true; $this->dirty = true;

View File

@ -56,6 +56,11 @@ class Editor {
*/ */
protected bool $shouldQuit = false; protected bool $shouldQuit = false;
/**
* @var int The amount to move the cursor off the left
*/
protected int $cursorLeftOffset = 0;
/** /**
* @var int The number of times to confirm you wish to quit * @var int The number of times to confirm you wish to quit
*/ */
@ -87,6 +92,8 @@ class Editor {
{ {
$this->statusMessage = StatusMessage::from('HELP: Ctrl-S = save | Ctrl-Q = quit | Ctrl-F = find'); $this->statusMessage = StatusMessage::from('HELP: Ctrl-S = save | Ctrl-Q = quit | Ctrl-F = find');
$this->cursor = Point::new(); $this->cursor = Point::new();
$this->cursor->x += $this->cursorLeftOffset;
$this->offset = Point::new(); $this->offset = Point::new();
$this->terminalSize = Terminal::size(); $this->terminalSize = Terminal::size();
@ -385,13 +392,13 @@ class Editor {
($fileRow >= $this->document->numRows) ($fileRow >= $this->document->numRows)
? $this->drawPlaceholderRow($y) ? $this->drawPlaceholderRow($y)
: $this->drawRow($fileRow); : $this->drawRow($fileRow, true);
$this->outputBuffer .= "\r\n"; $this->outputBuffer .= "\r\n";
} }
} }
protected function drawRow(int $rowIdx): void protected function drawRow(int $rowIdx, bool $lineNumbers): void
{ {
$row = $this->document->row($rowIdx); $row = $this->document->row($rowIdx);
if ( ! $row->isValid()) if ( ! $row->isValid())
@ -409,8 +416,46 @@ class Editor {
$len = $this->terminalSize->cols; $len = $this->terminalSize->cols;
} }
$chars = substr($row->render, $this->offset->x, (int)$len); if ($lineNumbers)
$hl = array_slice($row->hl, $this->offset->x, (int)$len); {
$this->drawLineNumbers($rowIdx);
}
$this->drawRowHighlighting($row, $len);
$this->outputBuffer .= ANSI::RESET_TEXT;
$this->outputBuffer .= ANSI::color(Color::FG_WHITE);
}
protected function drawLineNumbers(int $rowIdx): void
{
$rawColCount = match (true) {
$this->document->numRows > 50 => 3,
$this->document->numRows > 500 => 4,
$this->document->numRows > 5_000 => 5,
$this->document->numRows > 50_000 => 6,
$this->document->numRows > 500_000 => 7,
default => 2,
};
$rowNumber = $rowIdx + 1;
$digitLen = strlen("$rowNumber");
$frontPadding = str_repeat(' ', $rawColCount - $digitLen);
$rearPadding = str_repeat(' ', 2);
$output = sprintf("%s%d%s", $frontPadding, $rowNumber, $rearPadding);
$this->outputBuffer .= ANSI::RESET_TEXT;
$this->outputBuffer .= ANSI::color(Color::FG_WHITE);
$this->outputBuffer .= $output;
$this->cursorLeftOffset = strlen($output);
}
protected function drawRowHighlighting(Row $row, int $len): void
{
$chars = substr($row->render, $this->offset->x, $len);
$hl = array_slice($row->hl, $this->offset->x, $len);
$currentColor = -1; $currentColor = -1;
@ -454,9 +499,6 @@ class Editor {
$this->outputBuffer .= $ch; $this->outputBuffer .= $ch;
} }
} }
$this->outputBuffer .= ANSI::RESET_TEXT;
$this->outputBuffer .= ANSI::color(Color::FG_WHITE);
} }
protected function drawPlaceholderRow(int $y): void protected function drawPlaceholderRow(int $y): void
@ -548,9 +590,10 @@ class Editor {
$this->drawMessageBar(); $this->drawMessageBar();
// Specify the current cursor position // Specify the current cursor position
// The current 'x' position takes into account the length of the line number column
$this->outputBuffer .= ANSI::moveCursor( $this->outputBuffer .= ANSI::moveCursor(
$this->cursor->y - $this->offset->y, $this->cursor->y - $this->offset->y,
$this->renderX - $this->offset->x $this->renderX - $this->offset->x + $this->cursorLeftOffset,
); );
$this->outputBuffer .= ANSI::SHOW_CURSOR; $this->outputBuffer .= ANSI::SHOW_CURSOR;
@ -666,7 +709,7 @@ class Editor {
protected function moveCursor(string $key): void protected function moveCursor(string $key): void
{ {
$x = $this->cursor->x; $x = saturating_sub($this->cursor->x, $this->cursorLeftOffset);
$y = $this->cursor->y; $y = $this->cursor->y;
$row = $this->document->row($y); $row = $this->document->row($y);
if ( ! $row->isValid()) if ( ! $row->isValid())
@ -685,7 +728,7 @@ class Editor {
{ {
// Beginning of a line, go to end of previous line // Beginning of a line, go to end of previous line
$y--; $y--;
$x = $row->size - 1; $x = $this->document->row($y)->size - 1;
} }
break; break;
@ -735,7 +778,7 @@ class Editor {
break; break;
default: default:
// Do nothing return;
} }
// Snap cursor to the end of a row when moving // Snap cursor to the end of a row when moving
@ -749,8 +792,9 @@ class Editor {
} }
$this->cursor->x = $x; $this->cursor->x = $x;
$this->cursor->y = $y;
} }
$this->cursor->y = ($y >= $this->document->numRows) ? $this->document->numRows - 1 : $y;
} }
protected function insertChar(string $c): void protected function insertChar(string $c): void
@ -766,7 +810,7 @@ class Editor {
$this->document->delete($this->cursor); $this->document->delete($this->cursor);
} }
if ($ch === KeyType::BACKSPACE && ($this->cursor->x > 0 || $this->cursor->y > 0)) if ($ch === KeyType::BACKSPACE && ($this->cursor->x > $this->cursorLeftOffset || $this->cursor->y > 0))
{ {
$this->moveCursor(KeyType::ARROW_LEFT); $this->moveCursor(KeyType::ARROW_LEFT);
$this->document->delete($this->cursor); $this->document->delete($this->cursor);

View File

@ -115,7 +115,7 @@ class FileType {
'usize', '&str', 'Copy', 'Drop', 'From', 'Into', 'None', 'Self', 'Send', 'Some', 'usize', '&str', 'Copy', 'Drop', 'From', 'Into', 'None', 'Self', 'Send', 'Some',
'Sync', 'bool', 'char', 'i128', 'u128', 'Box', 'Err', 'Ord', 'Vec', 'dyn', 'f32', 'Sync', 'bool', 'char', 'i128', 'u128', 'Box', 'Err', 'Ord', 'Vec', 'dyn', 'f32',
'f64', 'i16', 'i32', 'i64', 'str', 'u16', 'u32', 'u64', 'Eq', 'Fn', 'Ok', 'i8', 'u8', 'f64', 'i16', 'i32', 'i64', 'str', 'u16', 'u32', 'u64', 'Eq', 'Fn', 'Ok', 'i8', 'u8',
'&mut self', '&mut', '&self', 'self', '&mut self', '&mut', '&self', 'self', '()',
], ],
[ [
'...', '=>', '..', '>>=', '<<=', '--', '%=', '>>', ':=', '++', '/=', '<<', '>=', '...', '=>', '..', '>>=', '<<=', '--', '%=', '>>', ':=', '++', '/=', '<<', '>=',

View File

@ -263,7 +263,14 @@ class Row {
|| $this->highlightCommonOperators($i, $syntax) || $this->highlightCommonOperators($i, $syntax)
|| $this->highlightNumber($i, $syntax) || $this->highlightNumber($i, $syntax)
) { ) {
continue; if ($i >= $this->rsize)
{
break;
}
else
{
continue;
}
} }
$i++; $i++;

View File

@ -189,6 +189,12 @@ function tabs_to_spaces(string $str, int $number = KILO_TAB_STOP): string
return str_replace(RawKeyCode::TAB, str_repeat(RawKeyCode::SPACE, $number), $str); return str_replace(RawKeyCode::TAB, str_repeat(RawKeyCode::SPACE, $number), $str);
} }
/**
* Get an understandable name for the type of error code
*
* @param int $code
* @return string
*/
function error_code_name(int $code): string function error_code_name(int $code): string
{ {
return match ($code) { return match ($code) {
@ -210,11 +216,28 @@ function error_code_name(int $code): string
}; };
} }
/**
* Add two integers, returning the sum, or if the
* sum is greater than $max, returning $max
*
* @param int $a
* @param int $b
* @param int $max
* @return int
*/
function saturating_add(int $a, int $b, int $max): int function saturating_add(int $a, int $b, int $max): int
{ {
return ($a + $b > $max) ? $max : $a + $b; return ($a + $b > $max) ? $max : $a + $b;
} }
/**
* Subtract $b from $a, returning the difference
* or 0, whichever is greater
*
* @param int $a
* @param int $b
* @return int
*/
function saturating_sub(int $a, int $b): int function saturating_sub(int $a, int $b): int
{ {
if ($b > $a) if ($b > $a)