Improve number highlighting, finish step 156

This commit is contained in:
Timothy Warren 2019-10-24 16:22:52 -04:00
parent a59bcfb9d1
commit 88afc3909e
2 changed files with 71 additions and 6 deletions

View File

@ -135,12 +135,29 @@ class Row {
{ {
$this->hl = array_fill(0, $this->rsize, Highlight::NORMAL); $this->hl = array_fill(0, $this->rsize, Highlight::NORMAL);
for ($i = 0; $i < $this->rsize; $i++) $prevSep = TRUE;
$i = 0;
while ($i < $this->rsize)
{ {
if (is_digit($this->render[$i])) $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))
)
{ {
$this->hl[$i] = Highlight::NUMBER; $this->hl[$i] = Highlight::NUMBER;
$i++;
$prevSep = FALSE;
continue;
} }
$prevSep = is_separator($char);
$i++;
} }
} }
} }
@ -497,6 +514,15 @@ class Editor {
static $lastMatch = -1; static $lastMatch = -1;
static $direction = 1; static $direction = 1;
static $savedHlLine = 0;
static $savedHl = [];
if ( ! empty($savedHl))
{
$this->rows[$savedHlLine]->hl = $savedHl;
$savedHl = [];
}
if ($key === "\r" || $key === "\x1b") if ($key === "\r" || $key === "\x1b")
{ {
$lastMatch = -1; $lastMatch = -1;
@ -536,16 +562,20 @@ class Editor {
$current = 0; $current = 0;
} }
$match = strpos($this->rows[$current]->render, $query); $row = $this->rows[$current];
$match = strpos($row->render, $query);
if ($match !== FALSE) if ($match !== FALSE)
{ {
$lastMatch = $current; $lastMatch = $current;
$this->cursorY = $current; $this->cursorY = $current;
$this->cursorX = $this->rowRxToCx($this->rows[$current], $match); $this->cursorX = $this->rowRxToCx($row, $match);
$this->rowOffset = $this->numRows; $this->rowOffset = $this->numRows;
$savedHlLine = $current;
$savedHl = $row->hl;
// Update the highlight array of the relevant row with the 'MATCH' type // Update the highlight array of the relevant row with the 'MATCH' type
array_replace_range($this->rows[$current]->hl, $match, strlen($query), Highlight::MATCH); array_replace_range($row->hl, $match, strlen($query), Highlight::MATCH);
break; break;
} }
@ -662,7 +692,8 @@ class Editor {
{ {
if ($currentColor !== -1) if ($currentColor !== -1)
{ {
$this->ab .= "\x1b[39m"; $this->ab .= "\x1b[39m"; // Reset foreground color
$this->ab .= "\x1b[0m"; // Reset background color
$currentColor = -1; $currentColor = -1;
} }
$this->ab .= $c[$i]; $this->ab .= $c[$i];
@ -673,6 +704,7 @@ class Editor {
if ($color !== $currentColor) if ($color !== $currentColor)
{ {
$currentColor = $color; $currentColor = $color;
$this->ab .= "\x1b[0m"; // Reset background color
$this->ab .= sprintf("\x1b[%dm", $color); $this->ab .= sprintf("\x1b[%dm", $color);
} }
$this->ab .= $c[$i]; $this->ab .= $c[$i];
@ -680,6 +712,7 @@ class Editor {
} }
$this->ab .= "\x1b[39m"; $this->ab .= "\x1b[39m";
$this->ab .= "\x1b[0m";
} }
$this->ab .= "\x1b[K"; // Clear the current line $this->ab .= "\x1b[K"; // Clear the current line

View File

@ -161,6 +161,18 @@ function is_digit(string $char): bool
return is_ascii($char) && ( $c > 0x2f && $c < 0x3a ); return is_ascii($char) && ( $c > 0x2f && $c < 0x3a );
} }
/**
* Does the one-character string contain ascii whitespace?
*
* @param string $char
* @return bool
*/
function is_space(string $char): bool
{
$ws = [' ', "\t", "\n", "\r", "\xa", "\xb", "\xc"];
return is_ascii($char) && in_array($char, $ws, TRUE);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ! Helper functions // ! Helper functions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -182,6 +194,26 @@ function get_ffi(): FFI
return $ffi; return $ffi;
} }
/**
* Does the one-character string contain a character that separates tokens?
*
* @param string $char
* @return bool
*/
function is_separator(string $char): bool
{
if ( ! is_ascii($char))
{
return FALSE;
}
// `strpos` is used instead of `strchr`/`strstr` as we don't care about the actual match
// while `strchr` would match the C version, it also returns the match
$isSep = (strpos(',.()+-/*=~%<>[];', $char) !== FALSE);
return is_space($char) || $char === "\0" || $isSep;
}
/** /**
* Pull input from the stdin stream. * Pull input from the stdin stream.
* *