Fix off-by-one highlighting error
timw4mail/php-kilo/pipeline/head This commit looks good Details

This commit is contained in:
Timothy Warren 2021-04-14 16:38:41 -04:00
parent a50c22c0e0
commit d0817b62c4
6 changed files with 69 additions and 57 deletions

View File

@ -541,10 +541,7 @@ class Editor {
{ {
$this->scroll(); $this->scroll();
$this->outputBuffer = ''; $this->outputBuffer = ANSI::HIDE_CURSOR . ANSI::RESET_CURSOR;
$this->outputBuffer .= ANSI::HIDE_CURSOR;
$this->outputBuffer .= ANSI::RESET_CURSOR;
$this->drawRows(); $this->drawRows();
$this->drawStatusBar(); $this->drawStatusBar();
@ -719,15 +716,11 @@ class Editor {
break; break;
case KeyType::PAGE_UP: case KeyType::PAGE_UP:
$y = ($y > $this->terminalSize->rows) $y = saturating_sub($y, $this->terminalSize->rows);
? $y - $this->terminalSize->rows
: 0;
break; break;
case KeyType::PAGE_DOWN: case KeyType::PAGE_DOWN:
$y = ($y + $this->terminalSize->rows < $this->document->numRows) $y = saturating_add($y, $this->terminalSize->rows, $this->document->numRows);
? $y + $this->terminalSize->rows
: $this->document->numRows;
break; break;
case KeyType::HOME: case KeyType::HOME:

View File

@ -202,6 +202,11 @@ class Row {
return; return;
} }
if ($this->parent->fileType->name === 'No filetype')
{
return;
}
$syntax = $this->parent->fileType->syntax; $syntax = $this->parent->fileType->syntax;
$mcs = $syntax->multiLineCommentStart; $mcs = $syntax->multiLineCommentStart;
@ -245,17 +250,16 @@ class Row {
} }
if ( if (
$this->highlightComment($i, $syntax) $this->highlightCharacter($i, $syntax)
|| $this->highlightComment($i, $syntax)
|| $this->highlightPrimaryKeywords($i, $syntax) || $this->highlightPrimaryKeywords($i, $syntax)
|| $this->highlightSecondaryKeywords($i, $syntax) || $this->highlightSecondaryKeywords($i, $syntax)
|| $this->highlightCharacter($i, $syntax)
|| $this->highlightString($i, $syntax) || $this->highlightString($i, $syntax)
|| $this->highlightNumber($i, $syntax)
|| $this->highlightOperators($i, $syntax) || $this->highlightOperators($i, $syntax)
|| $this->highlightCommonOperators($i)
|| $this->highlightCommonDelimeters($i) || $this->highlightCommonDelimeters($i)
|| $this->highlightCommonOperators($i)
|| $this->highlightNumber($i, $syntax)
) { ) {
$i++;
continue; continue;
} }
@ -266,7 +270,7 @@ class Row {
$this->hlOpenComment = $inComment; $this->hlOpenComment = $inComment;
if ($changed && $this->idx + 1 < $this->parent->numRows) if ($changed && $this->idx + 1 < $this->parent->numRows)
{ {
$this->parent->rows[$this->idx + 1]->highlight(); $this->parent->rows[$this->idx + 1]->update();
} }
} }
@ -294,16 +298,14 @@ class Row {
$nextChar = $this->render[$i]; $nextChar = $this->render[$i];
if ($nextChar !== '.' && ! is_digit($nextChar)) if ($nextChar !== '.' && ! is_digit($nextChar))
{ {
break; return true;
} }
}
else
{
break;
}
}
return true; continue;
}
break;
}
} }
return false; return false;
@ -330,7 +332,7 @@ class Row {
if (substr($this->render, $i, $klen) === $k && is_separator($nextChar)) if (substr($this->render, $i, $klen) === $k && is_separator($nextChar))
{ {
array_replace_range($this->hl, $i, $klen, $syntaxType); array_replace_range($this->hl, $i, $klen, $syntaxType);
$i += $klen - 1; $i += $klen;
return true; return true;
} }
@ -341,12 +343,17 @@ class Row {
protected function highlightChar(int &$i, array $chars, int $syntaxType): bool protected function highlightChar(int &$i, array $chars, int $syntaxType): bool
{ {
if ($this->hl[$i] !== Highlight::NORMAL)
{
return false;
}
$char = $this->render[$i]; $char = $this->render[$i];
if (in_array($char, $chars, TRUE)) if (in_array($char, $chars, TRUE))
{ {
$this->hl[$i] = $syntaxType; $this->hl[$i] = $syntaxType;
$i += 1; $i++;
return true; return true;
} }
@ -450,7 +457,7 @@ class Row {
return false; return false;
} }
if ($opts->strings() && $char === '"' || $char === '\'') if ($opts->strings() && ($char === '"' || $char === '\''))
{ {
$quote = $char; $quote = $char;
$this->hl[$i] = Highlight::STRING; $this->hl[$i] = Highlight::STRING;
@ -470,13 +477,11 @@ class Row {
} }
// End of the string! // End of the string!
$i++;
if ($char === $quote) if ($char === $quote)
{ {
$i++;
break; break;
} }
$i++;
} }
return true; return true;

View File

@ -4,7 +4,6 @@ namespace Aviat\Kilo\Tokens;
use PhpToken; use PhpToken;
use function Aviat\Kilo\str_contains;
use function Aviat\Kilo\tabs_to_spaces; use function Aviat\Kilo\tabs_to_spaces;
use const Aviat\Kilo\T_RAW; use const Aviat\Kilo\T_RAW;

View File

@ -138,7 +138,7 @@ function array_replace_range(array &$array, int $offset, int $length, mixed $val
* @param int|null $offset * @param int|null $offset
* @return bool * @return bool
*/ */
function str_contains(string $haystack, string $str, ?int $offset = NULL): bool function str_has(string $haystack, string $str, ?int $offset = NULL): bool
{ {
if (empty($str)) if (empty($str))
{ {
@ -208,4 +208,19 @@ function error_code_name(int $code): string
E_USER_DEPRECATED => 'User Deprecated', E_USER_DEPRECATED => 'User Deprecated',
default => 'Unknown', default => 'Unknown',
}; };
}
function saturating_add(int $a, int $b, int $max): int
{
return ($a + $b > $max) ? $max : $a + $b;
}
function saturating_sub(int $a, int $b): int
{
if ($b > $a)
{
return 0;
}
return $a - $b;
} }

View File

@ -13,7 +13,7 @@ use function Aviat\Kilo\is_ctrl;
use function Aviat\Kilo\is_digit; use function Aviat\Kilo\is_digit;
use function Aviat\Kilo\is_separator; use function Aviat\Kilo\is_separator;
use function Aviat\Kilo\is_space; use function Aviat\Kilo\is_space;
use function Aviat\Kilo\str_contains; use function Aviat\Kilo\str_has;
use function Aviat\Kilo\syntax_to_color; use function Aviat\Kilo\syntax_to_color;
use function Aviat\Kilo\tabs_to_spaces; use function Aviat\Kilo\tabs_to_spaces;
@ -99,20 +99,20 @@ class FunctionTest extends TestCase {
public function test_str_contains(): void public function test_str_contains(): void
{ {
// Search from string offset // Search from string offset
$this->assertTrue(str_contains(' vcd', 'vcd', 2)); $this->assertTrue(str_has(' vcd', 'vcd', 2));
$this->assertFalse(str_contains('', "\0")); $this->assertFalse(str_has('', "\0"));
// An empty search string returns false // An empty search string returns false
$this->assertFalse(str_contains('', '')); $this->assertFalse(str_has('', ''));
$this->assertTrue(str_contains('alphabet', 'phab')); $this->assertTrue(str_has('alphabet', 'phab'));
} }
public function test_tabs_to_spaces(): void public function test_tabs_to_spaces(): void
{ {
$original = "\t\t\t{"; $original = "\t\t\t{";
$this->assertFalse(str_contains(tabs_to_spaces($original), "\t")); $this->assertFalse(str_has(tabs_to_spaces($original), "\t"));
} }
public function test_array_replace_range_length_1(): void public function test_array_replace_range_length_1(): void

View File

@ -654,7 +654,7 @@
5, 5,
5, 5,
5, 5,
0 7
], ],
"idx": 16 "idx": 16
}, },
@ -678,7 +678,7 @@
13, 13,
13, 13,
13, 13,
0 7
], ],
"idx": 17 "idx": 17
}, },
@ -1495,10 +1495,10 @@
0, 0,
0, 0,
9, 9,
0, 6,
0, 6,
9, 9,
0 7
], ],
"idx": 49 "idx": 49
}, },
@ -1589,7 +1589,7 @@
"render": "};", "render": "};",
"hl": [ "hl": [
9, 9,
0 7
], ],
"idx": 53 "idx": 53
}, },
@ -1616,9 +1616,9 @@
0, 0,
0, 0,
9, 9,
0, 4,
0, 4,
0, 4,
0, 0,
0, 0,
0, 0,
@ -1650,7 +1650,7 @@
0, 0,
0, 0,
9, 9,
0 7
], ],
"idx": 55 "idx": 55
}, },
@ -1672,9 +1672,9 @@
0, 0,
0, 0,
9, 9,
0, 4,
0, 4,
0, 4,
0, 0,
0, 0,
0, 0,
@ -1734,7 +1734,7 @@
0, 0,
0, 0,
9, 9,
0 7
], ],
"idx": 56 "idx": 56
}, },
@ -2098,7 +2098,7 @@
"render": "};", "render": "};",
"hl": [ "hl": [
9, 9,
0 7
], ],
"idx": 66 "idx": 66
}, },
@ -2116,9 +2116,9 @@
0, 0,
0, 0,
9, 9,
0, 4,
0, 4,
0, 4,
7, 7,
0, 0,
4, 4,
@ -2130,7 +2130,7 @@
0, 0,
0, 0,
9, 9,
0 7
], ],
"idx": 67 "idx": 67
} }